common: prevent buffer overflow
[supercollider.git] / server / scsynth / SC_MiscCmds.cpp
blob47e974cb757b01039eace7cbf14f57f354a31bd6
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SC_Lib.h"
23 #include "SC_ComPort.h"
24 #include "SC_CoreAudio.h"
25 #include "SC_HiddenWorld.h"
26 #include "SC_Graph.h"
27 #include "SC_GraphDef.h"
28 #include "SC_Group.h"
29 #include "SC_UnitDef.h"
30 #include <stdexcept>
31 #include "SC_Lib_Cintf.h"
32 #include "SC_SequencedCommand.h"
33 #include <new>
34 #include "SC_Prototypes.h"
35 #include "scsynthsend.h"
37 extern int gMissingNodeID;
39 // returns number of bytes in an OSC string.
40 int OSCstrlen(char *strin);
42 Node* Msg_GetNode(World *inWorld, sc_msg_iter& msg)
44 Node *node;
45 if (msg.nextTag('i') == 's')
47 const char* loc = msg.gets();
48 int32 nodeID = msg.geti();
49 gMissingNodeID = nodeID;
50 node = World_GetNode(inWorld, nodeID);
51 while (*loc)
53 if (!node) return 0;
54 switch (*loc)
56 case 'h' :
57 if (!node->mIsGroup) return 0;
58 node = ((Group*)node)->mHead;
59 break;
60 case 't' :
61 if (!node->mIsGroup) return 0;
62 node = ((Group*)node)->mTail;
63 break;
64 case 'u' :
65 node = &node->mParent->mNode;
66 break;
67 case 'p' :
68 node = node->mPrev;
69 break;
70 case 'n' :
71 node = node->mNext;
72 break;
74 loc++;
77 else
79 int32 nodeID = msg.geti();
80 gMissingNodeID = nodeID;
81 node = World_GetNode(inWorld, nodeID);
83 return node;
86 Group* Msg_GetGroup(World *inWorld, sc_msg_iter& msg)
88 Node* node = Msg_GetNode(inWorld, msg);
89 return node && node->mIsGroup ? (Group*)node : 0;
92 Graph* Msg_GetGraph(World *inWorld, sc_msg_iter& msg)
94 Node* node = Msg_GetNode(inWorld, msg);
95 return !node || node->mIsGroup ? 0 : (Graph*)node;
98 SCErr meth_none(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
99 SCErr meth_none(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
101 return kSCErr_None;
104 SCErr meth_sync(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
105 SCErr meth_sync(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
107 CallSequencedCommand(SyncCmd, inWorld, inSize, inData, inReply);
108 return kSCErr_None;
111 SCErr meth_b_alloc(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
112 SCErr meth_b_alloc(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
114 CallSequencedCommand(BufAllocCmd, inWorld, inSize, inData, inReply);
115 return kSCErr_None;
118 SCErr meth_b_free(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
119 SCErr meth_b_free(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
121 CallSequencedCommand(BufFreeCmd, inWorld, inSize, inData, inReply);
123 return kSCErr_None;
126 SCErr meth_b_close(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
127 SCErr meth_b_close(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
129 CallSequencedCommand(BufCloseCmd, inWorld, inSize, inData, inReply);
131 return kSCErr_None;
134 SCErr meth_b_allocRead(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
135 SCErr meth_b_allocRead(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
137 CallSequencedCommand(BufAllocReadCmd, inWorld, inSize, inData, inReply);
139 return kSCErr_None;
142 SCErr meth_b_read(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
143 SCErr meth_b_read(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
145 CallSequencedCommand(BufReadCmd, inWorld, inSize, inData, inReply);
147 return kSCErr_None;
150 SCErr meth_b_allocReadChannel(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
151 SCErr meth_b_allocReadChannel(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
153 CallSequencedCommand(BufAllocReadChannelCmd, inWorld, inSize, inData, inReply);
155 return kSCErr_None;
158 SCErr meth_b_readChannel(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
159 SCErr meth_b_readChannel(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
161 CallSequencedCommand(BufReadChannelCmd, inWorld, inSize, inData, inReply);
163 return kSCErr_None;
166 SCErr meth_b_write(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
167 SCErr meth_b_write(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
169 CallSequencedCommand(BufWriteCmd, inWorld, inSize, inData, inReply);
171 return kSCErr_None;
174 SCErr meth_b_zero(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
175 SCErr meth_b_zero(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
177 CallSequencedCommand(BufZeroCmd, inWorld, inSize, inData, inReply);
178 return kSCErr_None;
182 SCErr meth_u_cmd(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
183 SCErr meth_u_cmd(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
185 return Unit_DoCmd(inWorld, inSize, inData);
188 SCErr meth_cmd(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
189 SCErr meth_cmd(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
191 return PlugIn_DoCmd(inWorld, inSize, inData, inReply);
196 SCErr meth_n_cmd(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
197 SCErr meth_n_cmd(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
199 sc_msg_iter msg(inSize, inData);
200 Node *node = Msg_GetNode(inWorld, msg);
201 if (!node) return kSCErr_NodeNotFound;
203 char *args = msg.rdpos;
204 int arglen = msg.remain();
206 //!! (node->mDef->fNodeCmd)(node, arglen, args);
208 return kSCErr_None;
212 SCErr meth_n_trace(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
213 SCErr meth_n_trace(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
215 sc_msg_iter msg(inSize, inData);
216 while (msg.remain()) {
217 Node *node = Msg_GetNode(inWorld, msg);
218 if (!node) return kSCErr_NodeNotFound;
220 Node_Trace(node);
223 return kSCErr_None;
226 SCErr meth_g_dumpTree(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
227 SCErr meth_g_dumpTree(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
229 sc_msg_iter msg(inSize, inData);
230 while (msg.remain()) {
231 Group *group = Msg_GetGroup(inWorld, msg);
232 if (!group) return kSCErr_GroupNotFound;
233 int32 flag = msg.geti();
234 if(flag) {
235 Group_DumpTreeAndControls(group);
236 } else {
237 Group_DumpTree(group);
241 return kSCErr_None;
244 //SCErr meth_g_queryTree(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
245 //SCErr meth_g_queryTree(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
247 // sc_msg_iter msg(inSize, inData);
248 // while (msg.remain()) {
249 // Group *group = Msg_GetGroup(inWorld, msg);
250 // if (!group) return kSCErr_GroupNotFound;
252 // // first count the total number of nodes to know how many tags the packet should have
253 // int numNodes = 1; // include this one
255 // Group_CountNodes(group, &numNodes);
257 // big_scpacket packet;
258 // packet.adds("/g_queryTree.reply");
259 // packet.maketags(numNodes * 3 + 1);
260 // packet.addtag(',');
262 // Group_QueryTree(group, &packet);
264 // if (packet.size()) {
265 // CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
266 // }
267 // }
268 // return kSCErr_None;
271 SCErr meth_g_queryTree(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
272 SCErr meth_g_queryTree(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
274 sc_msg_iter msg(inSize, inData);
275 while (msg.remain()) {
276 Group *group = Msg_GetGroup(inWorld, msg);
277 if (!group) return kSCErr_GroupNotFound;
278 big_scpacket packet;
279 packet.adds("/g_queryTree.reply");
280 int32 flag = msg.geti();
281 if(flag) {
282 // first count the total number of nodes to know how many tags the packet should have
283 int numNodes = 1; // include this one
284 int numControlsAndDefs = 0;
285 Group_CountNodeAndControlTags(group, &numNodes, &numControlsAndDefs);
286 // nodeID and numChildren + numControlsAndDefs + controlFlag
287 packet.maketags(numNodes * 2 + numControlsAndDefs + 2);
288 packet.addtag(',');
289 packet.addtag('i');
290 packet.addi(1); // include controls flag
291 Group_QueryTreeAndControls(group, &packet);
292 } else {
293 // first count the total number of nodes to know how many tags the packet should have
294 int numNodeTags = 2; // include this one
295 Group_CountNodeTags(group, &numNodeTags);
296 packet.maketags(numNodeTags + 2); // nodeID and numChildren
297 packet.addtag(',');
298 packet.addtag('i');
299 packet.addi(0); // include controls flag
300 Group_QueryTree(group, &packet);
303 if (packet.size()) {
304 CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
307 return kSCErr_None;
312 SCErr meth_n_run(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
313 SCErr meth_n_run(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
315 sc_msg_iter msg(inSize, inData);
317 while (msg.remain()) {
318 Node *node = Msg_GetNode(inWorld, msg);
319 if (!node) return kSCErr_NodeNotFound;
321 int32 run = msg.geti();
323 Node_SetRun(node, run);
326 return kSCErr_None;
329 SCErr meth_n_map(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
330 SCErr meth_n_map(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
332 sc_msg_iter msg(inSize, inData);
333 Node *node = Msg_GetNode(inWorld, msg);
334 if (!node) return kSCErr_NodeNotFound;
336 while (msg.remain() >= 8) {
337 if (msg.nextTag('i') == 's') {
338 int32* name = msg.gets4();
339 int bus = msg.geti();
340 Node_MapControl(node, Hash(name), name, 0, bus);
341 } else {
342 int32 index = msg.geti();
343 int32 bus = msg.geti();
344 Node_MapControl(node, index, bus);
347 return kSCErr_None;
350 SCErr meth_n_mapn(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
351 SCErr meth_n_mapn(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
353 sc_msg_iter msg(inSize, inData);
354 Node *node = Msg_GetNode(inWorld, msg);
355 if (!node) return kSCErr_NodeNotFound;
357 while (msg.remain() >= 12) {
358 if (msg.nextTag('i') == 's') {
359 int32* name = msg.gets4();
360 int32 hash = Hash(name);
361 int bus = msg.geti();
362 int n = msg.geti();
363 for (int i=0; i<n; ++i) {
364 Node_MapControl(node, hash, name, i, bus == -1 ? -1 : bus+i);
366 } else {
367 int32 index = msg.geti();
368 int32 bus = msg.geti();
369 int n = msg.geti();
370 for (int i=0; i<n; ++i) {
371 Node_MapControl(node, index+i, bus == -1 ? -1 : bus+i);
375 return kSCErr_None;
378 SCErr meth_n_mapa(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
379 SCErr meth_n_mapa(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
381 sc_msg_iter msg(inSize, inData);
382 Node *node = Msg_GetNode(inWorld, msg);
383 if (!node) return kSCErr_NodeNotFound;
385 while (msg.remain() >= 8) {
386 if (msg.nextTag('i') == 's') {
387 int32* name = msg.gets4();
388 int bus = msg.geti();
389 Node_MapAudioControl(node, Hash(name), name, 0, bus);
390 } else {
391 int32 index = msg.geti();
392 int32 bus = msg.geti();
393 Node_MapAudioControl(node, index, bus);
396 return kSCErr_None;
399 SCErr meth_n_mapan(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
400 SCErr meth_n_mapan(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
402 sc_msg_iter msg(inSize, inData);
403 Node *node = Msg_GetNode(inWorld, msg);
404 if (!node) return kSCErr_NodeNotFound;
406 while (msg.remain() >= 12) {
407 if (msg.nextTag('i') == 's') {
408 int32* name = msg.gets4();
409 int32 hash = Hash(name);
410 int bus = msg.geti();
411 int n = msg.geti();
412 for (int i=0; i<n; ++i) {
413 Node_MapAudioControl(node, hash, name, i, bus == -1 ? -1 : bus+i);
415 } else {
416 int32 index = msg.geti();
417 int32 bus = msg.geti();
418 int n = msg.geti();
419 for (int i=0; i<n; ++i) {
420 Node_MapAudioControl(node, index+i, bus == -1 ? -1 : bus+i);
424 return kSCErr_None;
427 SCErr meth_n_set(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
428 SCErr meth_n_set(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
430 sc_msg_iter msg(inSize, inData);
431 Node *node = Msg_GetNode(inWorld, msg);
432 if (!node) return kSCErr_NodeNotFound;
433 while( msg.remain()>=8) {
434 int i = 0;
435 int loop = 0;
436 if (msg.nextTag('i') == 's') {
437 int32* name = msg.gets4();
438 int32 hash = Hash(name);
439 do {
440 switch (msg.nextTag('f') ) {
441 case 'f' :
442 case 'i' :
444 float32 value = msg.getf();
445 Node_SetControl(node, hash, name, i, value);
446 ++i;
447 break;
449 case 's' :
451 const char* string = msg.gets();
452 if ( *string == 'c') {
453 int bus = sc_atoi(string+1);
454 Node_MapControl(node, hash, name, i, bus);
455 ++i;
457 if ( *string == 'a') {
458 int bus = sc_atoi(string+1);
459 Node_MapAudioControl(node, hash, name, i, bus);
460 ++i;
462 break;
464 case ']':
465 msg.count++;
466 loop--;
467 break;
468 case '[':
469 msg.count++;
470 loop++;
471 break;
474 while (loop);
475 } else {
476 int32 index = msg.geti();
477 do {
478 switch (msg.nextTag('f') ) {
479 case 'f' :
480 case 'i' :
482 float32 value = msg.getf();
483 Node_SetControl(node, index + i, value);
484 ++i;
485 break;
487 case 's' :
489 const char* string = msg.gets();
490 if ( *string == 'c') {
491 int bus = sc_atoi(string+1);
492 Node_MapControl(node, index + i, bus);
493 ++i;
495 if ( *string == 'a') {
496 int bus = sc_atoi(string+1);
497 Node_MapAudioControl(node, index + i, bus);
498 ++i;
500 break;
502 case ']':
503 msg.count++;
504 loop--;
505 break;
506 case '[':
507 msg.count++;
508 loop++;
509 break;
512 while (loop);
517 // int i = 0;
518 // int loop = 0;
519 // if (msg.nextTag('i') == 's') {
520 // int32* name = msg.gets4();
521 // int32 hash = Hash(name);
522 // if (msg.nextTag('f') == '[' ) {
523 // msg.count++;
524 // loop = 1;
525 // }
526 // do {
527 // if (msg.nextTag('f') == 's' ) {
528 // const char* string = msg.gets();
529 // if ( *string == 'c') {
530 // int bus = sc_atoi(string+1);
531 // Node_MapControl(node, hash, name, i, bus);
532 // }
533 // } else {
534 // if (msg.nextTag('f') == ']' ) {
535 // msg.count++;
536 // loop = 0;
537 // } else {
538 // float32 value = msg.getf();
539 // Node_SetControl(node, hash, name, i, value);
540 // }
541 // }
542 // ++i;
543 // }
544 // while (loop);
545 // } else {
546 // int32 index = msg.geti();
547 // if (msg.nextTag('f') == '[' ) {
548 // msg.count++;
549 // loop = 1;
550 // }
551 // do {
552 // if (msg.nextTag('f') == 's') {
553 // const char* string = msg.gets();
554 // if (*string == 'c') {
555 // int bus = sc_atoi(string+1);
556 // Node_MapControl(node, index + i, bus);
557 // }
558 // } else {
559 // if (msg.nextTag('f') == ']' ) {
560 // msg.count++;
561 // loop = 0;
562 // } else {
563 // float32 value = msg.getf();
564 // Node_SetControl(node, index + i, value);
565 // }
566 // }
567 // ++i;
568 // }
569 // while (loop);
570 // }
571 // }
572 return kSCErr_None;
575 SCErr meth_n_setn(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
576 SCErr meth_n_setn(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
578 sc_msg_iter msg(inSize, inData);
579 Node *node = Msg_GetNode(inWorld, msg);
580 if (!node) return kSCErr_NodeNotFound;
582 while (msg.remain()) {
583 if (msg.nextTag('i') == 's') {
584 int32* name = msg.gets4();
585 int32 hash = Hash(name);
586 int32 n = msg.geti();
587 for (int i=0; msg.remain() && i<n; ++i) {
588 if (msg.nextTag('f') == 's') {
589 const char* string = msg.gets();
590 if (*string == 'c') {
591 int bus = sc_atoi(string+1);
592 Node_MapControl(node, hash, name, i, bus);
594 if (*string == 'a') {
595 int bus = sc_atoi(string+1);
596 Node_MapAudioControl(node, hash, name, i, bus);
599 } else {
600 float32 value = msg.getf();
601 Node_SetControl(node, hash, name, i, value);
604 } else {
605 int32 index = msg.geti();
606 int32 n = msg.geti();
607 for (int i=0; msg.remain() && i<n; ++i) {
608 if (msg.nextTag('f') == 's') {
609 const char* string = msg.gets();
610 if (*string == 'c') {
611 int bus = sc_atoi(string+1);
612 Node_MapControl(node, index+i, bus);
614 if (*string == 'a') {
615 int bus = sc_atoi(string+1);
616 Node_MapAudioControl(node, index+i, bus);
618 } else {
619 float32 value = msg.getf();
620 Node_SetControl(node, index+i, value);
625 return kSCErr_None;
628 SCErr meth_n_fill(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
629 SCErr meth_n_fill(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
631 sc_msg_iter msg(inSize, inData);
632 Node *node = Msg_GetNode(inWorld, msg);
633 if (!node) return kSCErr_NodeNotFound;
635 while (msg.remain() >= 12)
637 if (msg.nextTag('i') == 's') {
638 int32* name = msg.gets4();
639 int32 hash = Hash(name);
640 int32 n = msg.geti();
641 float32 value = msg.getf();
643 for (int i=0; i<n; ++i) {
644 Node_SetControl(node, hash, name, i, value);
647 if (msg.nextTag('f') == 's') {
648 const char* string = msg.gets();
649 if (*string == 'c') {
650 int bus = sc_atoi(string+1);
651 for (int i=0; i<n; ++i) {
652 Node_MapControl(node, hash, name, i, bus+i);
655 } else {
656 float32 value = msg.getf();
657 for (int i=0; i<n; ++i) {
658 Node_SetControl(node, hash, name, i, value);
661 } else {
662 int32 index = msg.geti();
663 int32 n = msg.geti();
664 float32 value = msg.getf();
666 for (int i=0; i<n; ++i) {
667 Node_SetControl(node, index+i, value);
669 if (msg.nextTag('f') == 's') {
670 const char* string = msg.gets();
671 if (*string == 'c') {
672 int bus = sc_atoi(string+1);
673 for (int i=0; i<n; ++i) {
674 Node_MapControl(node, index+i, bus+i);
677 } else {
678 float32 value = msg.getf();
679 for (int i=0; i<n; ++i) {
680 Node_SetControl(node, index+i, value);
686 return kSCErr_None;
690 SCErr meth_n_query(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
691 SCErr meth_n_query(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
693 sc_msg_iter msg(inSize, inData);
695 while (msg.remain()) {
696 Node *node = Msg_GetNode(inWorld, msg);
697 if (!node) return kSCErr_NodeNotFound;
699 Node_StateMsg(node, kNode_Info);
701 return kSCErr_None;
704 SCErr meth_b_query(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
705 SCErr meth_b_query(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
707 sc_msg_iter msg(inSize, inData);
709 small_scpacket packet;
711 int numbufs = msg.remain() >> 2;
712 packet.adds("/b_info");
713 packet.maketags(numbufs * 4 + 1);
714 packet.addtag(',');
716 while (msg.remain()) {
717 int bufindex = msg.geti();
718 SndBuf* buf = World_GetBuf(inWorld, bufindex);
720 packet.addtag('i');
721 packet.addtag('i');
722 packet.addtag('i');
723 packet.addtag('f');
724 packet.addi(bufindex);
725 packet.addi(buf->frames);
726 packet.addi(buf->channels);
727 packet.addf(buf->samplerate);
730 if (packet.size()) {
731 CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
734 return kSCErr_None;
739 SCErr meth_d_load(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
740 SCErr meth_d_load(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
742 CallSequencedCommand(LoadSynthDefCmd, inWorld, inSize, inData, inReply);
744 return kSCErr_None;
748 SCErr meth_d_recv(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
749 SCErr meth_d_recv(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
751 CallSequencedCommand(RecvSynthDefCmd, inWorld, inSize, inData, inReply);
753 return kSCErr_None;
757 SCErr meth_d_loadDir(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
758 SCErr meth_d_loadDir(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
760 CallSequencedCommand(LoadSynthDefDirCmd, inWorld, inSize, inData, inReply);
762 return kSCErr_None;
765 SCErr meth_d_freeAll(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
766 SCErr meth_d_freeAll(World *inWorld, int /*inSize*/, char * /*inData*/, ReplyAddress* /*inReply*/)
768 World_FreeAllGraphDefs(inWorld);
769 return kSCErr_None;
772 SCErr meth_d_free(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
773 SCErr meth_d_free(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
775 sc_msg_iter msg(inSize, inData);
776 while (msg.remain()) {
777 int32* defname = msg.gets4();
778 if (!defname) return kSCErr_SynthDefNotFound;
779 GraphDef_Remove(inWorld, defname);
781 return kSCErr_None;
785 SCErr meth_s_new(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
786 SCErr meth_s_new(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
788 SCErr err;
789 sc_msg_iter msg(inSize, inData);
790 int32 *defname = msg.gets4();
791 if (!defname) return kSCErr_WrongArgType;
793 int32 nodeID = msg.geti();
794 int32 addAction = msg.geti();
796 GraphDef *def = World_GetGraphDef(inWorld, defname);
797 if (!def) {
798 scprintf("*** ERROR: SynthDef %s not found\n", (char*)defname);
799 return kSCErr_SynthDefNotFound;
802 Graph *graph = 0;
803 switch (addAction) {
804 case 0 : {
805 Group *group = Msg_GetGroup(inWorld, msg);
806 if (!group) return kSCErr_GroupNotFound;
807 err = Graph_New(inWorld, def, nodeID, &msg, &graph,true);//true for normal args
808 if (err) return err;
809 if (!graph) return kSCErr_Failed;
810 Group_AddHead(group, &graph->mNode);
811 } break;
812 case 1 : {
813 Group *group = Msg_GetGroup(inWorld, msg);
814 if (!group) return kSCErr_GroupNotFound;
815 err = Graph_New(inWorld, def, nodeID, &msg, &graph,true);
816 if (err) return err;
817 Group_AddTail(group, &graph->mNode);
818 } break;
819 case 2 : {
820 Node *beforeThisNode = Msg_GetNode(inWorld, msg);
821 if (!beforeThisNode) return kSCErr_NodeNotFound;
822 err = Graph_New(inWorld, def, nodeID, &msg, &graph,true);
823 if (err) return err;
824 Node_AddBefore(&graph->mNode, beforeThisNode);
825 } break;
826 case 3 : {
827 Node *afterThisNode = Msg_GetNode(inWorld, msg);
828 if (!afterThisNode) return kSCErr_NodeNotFound;
829 err = Graph_New(inWorld, def, nodeID, &msg, &graph,true);
830 if (err) return err;
831 Node_AddAfter(&graph->mNode, afterThisNode);
832 } break;
833 case 4 : {
834 Node *replaceThisNode = Msg_GetNode(inWorld, msg);
835 if (!replaceThisNode) return kSCErr_NodeNotFound;
836 err = Graph_New(inWorld, def, nodeID, &msg, &graph,true);
837 if (err) return err;
838 Node_Replace(&graph->mNode, replaceThisNode);
839 } break;
840 default: return kSCErr_Failed;
842 Node_StateMsg(&graph->mNode, kNode_Go);
843 return kSCErr_None;
846 SCErr meth_s_newargs(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
847 SCErr meth_s_newargs(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
849 SCErr err;
850 sc_msg_iter msg(inSize, inData);
851 int32 *defname = msg.gets4();
852 if (!defname) return kSCErr_WrongArgType;
854 int32 nodeID = msg.geti();
855 int32 addAction = msg.geti();
857 GraphDef *def = World_GetGraphDef(inWorld, defname);
858 if (!def) {
859 scprintf("*** ERROR: SynthDef %s not found\n", (char*)defname);
860 return kSCErr_SynthDefNotFound;
863 Graph *graph = 0;
864 switch (addAction) {
865 case 0 : {
866 Group *group = Msg_GetGroup(inWorld, msg);
867 if (!group) return kSCErr_GroupNotFound;
868 err = Graph_New(inWorld, def, nodeID, &msg, &graph,false);//false for setn type args
869 if (err) return err;
870 if (!graph) return kSCErr_Failed;
871 Group_AddHead(group, &graph->mNode);
872 } break;
873 case 1 : {
874 Group *group = Msg_GetGroup(inWorld, msg);
875 if (!group) return kSCErr_GroupNotFound;
876 err = Graph_New(inWorld, def, nodeID, &msg, &graph,false);
877 if (err) return err;
878 Group_AddTail(group, &graph->mNode);
879 } break;
880 case 2 : {
881 Node *beforeThisNode = Msg_GetNode(inWorld, msg);
882 if (!beforeThisNode) return kSCErr_NodeNotFound;
883 err = Graph_New(inWorld, def, nodeID, &msg, &graph,false);
884 if (err) return err;
885 Node_AddBefore(&graph->mNode, beforeThisNode);
886 } break;
887 case 3 : {
888 Node *afterThisNode = Msg_GetNode(inWorld, msg);
889 if (!afterThisNode) return kSCErr_NodeNotFound;
890 err = Graph_New(inWorld, def, nodeID, &msg, &graph,false);
891 if (err) return err;
892 Node_AddAfter(&graph->mNode, afterThisNode);
893 } break;
894 case 4 : {
895 Node *replaceThisNode = Msg_GetNode(inWorld, msg);
896 if (!replaceThisNode) return kSCErr_NodeNotFound;
897 err = Graph_New(inWorld, def, nodeID, &msg, &graph,false);
898 if (err) return err;
899 Node_Replace(&graph->mNode, replaceThisNode);
900 } break;
901 default: return kSCErr_Failed;
903 Node_StateMsg(&graph->mNode, kNode_Go);
904 return kSCErr_None;
907 SCErr meth_g_new(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
908 SCErr meth_g_new(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
910 SCErr err;
912 sc_msg_iter msg(inSize, inData);
913 while (msg.remain()) {
914 int32 newGroupID = msg.geti();
915 int32 addAction = msg.geti();
917 Group *newGroup = 0;
918 switch (addAction) {
919 case 0 : {
920 Group *group = Msg_GetGroup(inWorld, msg);
921 if (!group) return kSCErr_GroupNotFound;
922 err = Group_New(inWorld, newGroupID, &newGroup);
923 if (err) {
924 if (err == kSCErr_DuplicateNodeID) {
925 newGroup = World_GetGroup(inWorld, newGroupID);
926 if (!newGroup || !newGroup->mNode.mParent || newGroup->mNode.mParent != group)
927 return err;
928 } else return err;
929 } else {
930 Group_AddHead(group, &newGroup->mNode);
932 } break;
933 case 1 : {
934 Group *group = Msg_GetGroup(inWorld, msg);
935 if (!group) return kSCErr_GroupNotFound;
936 err = Group_New(inWorld, newGroupID, &newGroup);
937 if (err) {
938 if (err == kSCErr_DuplicateNodeID) {
939 newGroup = World_GetGroup(inWorld, newGroupID);
940 if (!newGroup || !newGroup->mNode.mParent || newGroup->mNode.mParent != group)
941 return err;
942 } else return err;
943 } else {
944 Group_AddTail(group, &newGroup->mNode);
946 } break;
947 case 2 : {
948 Node *beforeThisNode = Msg_GetNode(inWorld, msg);
949 if (!beforeThisNode) return kSCErr_TargetNodeNotFound;
950 err = Group_New(inWorld, newGroupID, &newGroup);
951 if (err) {
952 if (err == kSCErr_DuplicateNodeID) {
953 newGroup = World_GetGroup(inWorld, newGroupID);
954 if (!newGroup || !newGroup->mNode.mParent || newGroup->mNode.mParent->mNode.mID != beforeThisNode->mParent->mNode.mID)
955 return err;
956 } else return err;
957 } else {
958 Node_AddBefore(&newGroup->mNode, beforeThisNode);
960 } break;
961 case 3 : {
962 Node *afterThisNode = Msg_GetNode(inWorld, msg);
963 if (!afterThisNode) return kSCErr_TargetNodeNotFound;
964 err = Group_New(inWorld, newGroupID, &newGroup);
965 if (err) {
966 if (err == kSCErr_DuplicateNodeID) {
967 newGroup = World_GetGroup(inWorld, newGroupID);
968 if (!newGroup || !newGroup->mNode.mParent || newGroup->mNode.mParent->mNode.mID != afterThisNode->mParent->mNode.mID)
969 return err;
970 } else return err;
971 } else {
972 Node_AddAfter(&newGroup->mNode, afterThisNode);
974 } break;
975 case 4 : {
976 Node *replaceThisNode = Msg_GetNode(inWorld, msg);
977 if (!replaceThisNode) return kSCErr_TargetNodeNotFound;
978 err = Group_New(inWorld, newGroupID, &newGroup);
979 if (err) return err;
980 Node_Replace(&newGroup->mNode, replaceThisNode);
981 } break;
982 default: return kSCErr_Failed;
985 Node_StateMsg(&newGroup->mNode, kNode_Go);
988 return kSCErr_None;
991 SCErr meth_p_new(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
992 SCErr meth_p_new(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
994 /* we emulate the concept of parallel groups by using sequential groups */
995 return meth_g_new(inWorld, inSize, inData, inReply);
998 SCErr meth_n_free(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
999 SCErr meth_n_free(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1001 sc_msg_iter msg(inSize, inData);
1003 while (msg.remain()) {
1004 Node *node = Msg_GetNode(inWorld, msg);
1005 if (!node) return kSCErr_NodeNotFound;
1007 Node_Delete(node);
1010 return kSCErr_None;
1013 SCErr meth_n_before(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1014 SCErr meth_n_before(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1016 sc_msg_iter msg(inSize, inData);
1018 Node *prevNode = 0;
1019 Node *prevTarget = 0;
1020 while (msg.remain()) {
1021 Node *node = Msg_GetNode(inWorld, msg);
1022 Node *target = Msg_GetNode(inWorld, msg);
1024 if (!node || !target) continue; // tolerate failure
1026 if (prevNode && prevNode != node)
1028 // move the last pair that succeeded
1029 Node_Remove(prevNode);
1030 Node_AddBefore(prevNode, prevTarget);
1031 Node_StateMsg(prevNode, kNode_Move);
1034 prevNode = node;
1035 prevTarget = target;
1037 if (prevNode && prevNode != prevTarget)
1039 // move the last pair that succeeded
1040 Node_Remove(prevNode);
1041 Node_AddBefore(prevNode, prevTarget);
1042 Node_StateMsg(prevNode, kNode_Move);
1045 return kSCErr_None;
1048 SCErr meth_n_after(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1049 SCErr meth_n_after(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1051 sc_msg_iter msg(inSize, inData);
1053 Node *prevNode = 0;
1054 Node *prevTarget = 0;
1055 while (msg.remain()) {
1056 Node *node = Msg_GetNode(inWorld, msg);
1057 Node *target = Msg_GetNode(inWorld, msg);
1059 if (!node || !target) continue; // tolerate failure
1061 if (prevNode && prevNode != node)
1063 // move the last pair that succeeded
1064 Node_Remove(prevNode);
1065 Node_AddAfter(prevNode, prevTarget);
1066 Node_StateMsg(prevNode, kNode_Move);
1069 prevNode = node;
1070 prevTarget = target;
1072 if (prevNode)
1074 // move the last pair that succeeded
1075 Node_Remove(prevNode);
1076 Node_AddAfter(prevNode, prevTarget);
1077 Node_StateMsg(prevNode, kNode_Move);
1080 return kSCErr_None;
1083 SCErr meth_n_order(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1084 SCErr meth_n_order(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1086 SCErr err;
1088 Node *prevNode = 0;
1089 Node *node = 0;
1091 sc_msg_iter msg(inSize, inData);
1092 int32 addAction = msg.geti();
1094 // place the first node in the list based on target and addAction
1095 switch (addAction) {
1096 case 0 : {
1097 Group *group = Msg_GetGroup(inWorld, msg);
1098 if (!group) return kSCErr_GroupNotFound;
1099 while(!node && msg.remain()) {
1100 node = Msg_GetNode(inWorld, msg);
1101 if(!node) scprintf("Warning Node not found\n");
1103 if (!node) return kSCErr_NodeNotFound;
1105 Group *prevGroup = node->mParent;
1107 Node_Remove(node);
1109 Group_AddHead(group, node);
1111 if (group != prevGroup) {
1112 Node_StateMsg(node, kNode_Move);
1115 prevNode = node;
1117 } break;
1118 case 1 : {
1119 Group *group = Msg_GetGroup(inWorld, msg);
1120 if (!group) return kSCErr_GroupNotFound;
1121 while(!node && msg.remain()) {
1122 node = Msg_GetNode(inWorld, msg);
1123 if(!node) scprintf("Warning Node not found\n");
1125 if (!node) return kSCErr_NodeNotFound;
1127 Group *prevGroup = node->mParent;
1129 Node_Remove(node);
1131 Group_AddTail(group, node);
1133 if (group != prevGroup) {
1134 Node_StateMsg(node, kNode_Move);
1137 prevNode = node;
1139 } break;
1140 case 2 : {
1141 Node *beforeNode = Msg_GetNode(inWorld, msg);
1142 if (!beforeNode) return kSCErr_TargetNodeNotFound;
1143 while(!node && msg.remain()) {
1144 node = Msg_GetNode(inWorld, msg);
1145 if(!node) scprintf("Warning Node not found\n");
1147 if (!node) return kSCErr_NodeNotFound;
1150 Node_Remove(node);
1151 Node_AddBefore(node, beforeNode);
1152 Node_StateMsg(node, kNode_Move);
1154 prevNode = node;
1155 } break;
1156 case 3 : {
1157 Node *afterNode = Msg_GetNode(inWorld, msg);
1158 if (!afterNode) return kSCErr_TargetNodeNotFound;
1159 while(!node && msg.remain()) {
1160 node = Msg_GetNode(inWorld, msg);
1161 if(!node) scprintf("Warning Node not found\n");
1163 if (!node) return kSCErr_NodeNotFound;
1166 Node_Remove(node);
1167 Node_AddAfter(node, afterNode);
1168 Node_StateMsg(node, kNode_Move);
1170 prevNode = node;
1171 } break;
1172 default: return kSCErr_Failed;
1175 // now iterate through in order
1176 while (msg.remain()) {
1177 node = Msg_GetNode(inWorld, msg);
1178 if(!node) {
1179 scprintf("Warning Node not found\n");
1180 continue;
1182 Node_Remove(node);
1183 Node_AddAfter(node, prevNode);
1184 Node_StateMsg(node, kNode_Move);
1186 prevNode = node;
1189 return kSCErr_None;
1192 SCErr meth_g_head(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1193 SCErr meth_g_head(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1195 sc_msg_iter msg(inSize, inData);
1196 while (msg.remain()) {
1197 Group *group = Msg_GetGroup(inWorld, msg);
1198 if (!group) return kSCErr_GroupNotFound;
1200 Node *node = Msg_GetNode(inWorld, msg);
1201 if (!node) return kSCErr_NodeNotFound;
1203 Group *prevGroup = node->mParent;
1205 Node_Remove(node);
1207 Group_AddHead(group, node);
1209 if (group != prevGroup) {
1210 Node_StateMsg(node, kNode_Move);
1213 return kSCErr_None;
1216 SCErr meth_g_tail(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1217 SCErr meth_g_tail(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1219 sc_msg_iter msg(inSize, inData);
1220 while (msg.remain()) {
1221 Group *group = Msg_GetGroup(inWorld, msg);
1222 if (!group) return kSCErr_GroupNotFound;
1224 Node *node = Msg_GetNode(inWorld, msg);
1225 if (!node) return kSCErr_NodeNotFound;
1227 //Group *prevGroup = node->mParent;
1229 Node_Remove(node);
1230 Group_AddTail(group, node);
1232 //if (group != prevGroup) {
1233 Node_StateMsg(node, kNode_Move);
1236 return kSCErr_None;
1239 SCErr meth_g_insert(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1240 SCErr meth_g_insert(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1242 sc_msg_iter msg(inSize, inData);
1243 while (msg.remain()) {
1244 Group *group = Msg_GetGroup(inWorld, msg);
1245 if (!group) return kSCErr_GroupNotFound;
1247 Node *node = Msg_GetNode(inWorld, msg);
1248 if (!node) return kSCErr_NodeNotFound;
1250 Group *prevGroup = node->mParent;
1252 int index = msg.geti();
1254 Node_Remove(node);
1255 Group_Insert(group, node, index);
1257 if (group != prevGroup) {
1258 Node_StateMsg(node, kNode_Move);
1261 return kSCErr_None;
1264 SCErr meth_g_freeAll(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1265 SCErr meth_g_freeAll(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1267 sc_msg_iter msg(inSize, inData);
1268 while (msg.remain()) {
1269 Group *group = Msg_GetGroup(inWorld, msg);
1270 if (!group) return kSCErr_GroupNotFound;
1272 Group_DeleteAll(group);
1274 return kSCErr_None;
1277 SCErr meth_g_deepFree(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1278 SCErr meth_g_deepFree(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1280 sc_msg_iter msg(inSize, inData);
1281 while (msg.remain()) {
1282 Group *group = Msg_GetGroup(inWorld, msg);
1283 if (!group) return kSCErr_GroupNotFound;
1285 Group_DeepFreeGraphs(group);
1287 return kSCErr_None;
1292 SCErr meth_status(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1293 SCErr meth_status(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
1295 CallSequencedCommand(AudioStatusCmd, inWorld, inSize, inData, inReply);
1296 return kSCErr_None;
1299 SCErr meth_quit(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1300 SCErr meth_quit(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
1302 CallSequencedCommand(AudioQuitCmd, inWorld, inSize, inData, inReply);
1303 return kSCErr_None;
1306 SCErr meth_clearSched(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1307 SCErr meth_clearSched(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
1309 if(inWorld->mRealTime){
1310 inWorld->hw->mAudioDriver->ClearSched();
1312 return kSCErr_None;
1315 SCErr meth_dumpOSC(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1316 SCErr meth_dumpOSC(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
1318 sc_msg_iter msg(inSize, inData);
1319 inWorld->mDumpOSC = msg.geti();
1320 return kSCErr_None;
1323 SCErr meth_b_set(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1324 SCErr meth_b_set(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1326 sc_msg_iter msg(inSize, inData);
1327 int bufindex = msg.geti();
1328 SndBuf* buf = World_GetBuf(inWorld, bufindex);
1329 if (!buf) return kSCErr_Failed;
1331 float *data = buf->data;
1332 uint32 numSamples = buf->samples;
1334 while (msg.remain() >= 8)
1336 uint32 sampleIndex = msg.geti();
1337 float32 value = msg.getf();
1338 if (sampleIndex < numSamples)
1340 data[sampleIndex] = value;
1341 } else return kSCErr_IndexOutOfRange;
1344 return kSCErr_None;
1347 SCErr meth_b_setn(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1348 SCErr meth_b_setn(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1350 sc_msg_iter msg(inSize, inData);
1351 int bufindex = msg.geti();
1352 SndBuf* buf = World_GetBuf(inWorld, bufindex);
1353 if (!buf) return kSCErr_Failed;
1355 float *data = buf->data;
1356 int numSamples = buf->samples;
1358 while (msg.remain()) {
1359 int32 start = msg.geti();
1360 int32 n = msg.geti();
1361 int32 end = start+n-1;
1363 if (end < 0 || start >= numSamples) continue;
1365 start = sc_clip(start, 0, numSamples-1);
1366 end = sc_clip(end, 0, numSamples-1);
1368 for (int i=start; msg.remain() && i<=end; ++i) {
1369 float32 value = msg.getf();
1370 data[i] = value;
1374 return kSCErr_None;
1378 SCErr meth_b_fill(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1379 SCErr meth_b_fill(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1381 sc_msg_iter msg(inSize, inData);
1382 int bufindex = msg.geti();
1383 SndBuf* buf = World_GetBuf(inWorld, bufindex);
1384 if (!buf) return kSCErr_Failed;
1386 float *data = buf->data;
1387 int numSamples = buf->samples;
1389 while (msg.remain() >= 12)
1391 int32 start = msg.geti();
1392 int32 n = msg.geti();
1393 float32 value = msg.getf();
1394 int32 end = start+n-1;
1396 if (end < 0 || start >= numSamples) continue;
1398 start = sc_clip(start, 0, numSamples-1);
1399 end = sc_clip(end, 0, numSamples-1);
1401 for (int i=start; i<=end; ++i) data[i] = value;
1404 return kSCErr_None;
1407 SCErr meth_b_gen(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1408 SCErr meth_b_gen(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
1410 CallSequencedCommand(BufGenCmd, inWorld, inSize, inData, inReply);
1412 return kSCErr_None;
1416 SCErr meth_c_set(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1417 SCErr meth_c_set(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1419 sc_msg_iter msg(inSize, inData);
1421 float *data = inWorld->mControlBus;
1422 int32 *touched = inWorld->mControlBusTouched;
1423 int32 bufCounter = inWorld->mBufCounter;
1424 uint32 maxIndex = inWorld->mNumControlBusChannels;
1426 while (msg.remain() >= 8)
1428 uint32 index = msg.geti();
1429 float32 value = msg.getf();
1430 if (index < maxIndex)
1432 data[index] = value;
1433 touched[index] = bufCounter;
1434 } else return kSCErr_IndexOutOfRange;
1437 return kSCErr_None;
1440 SCErr meth_c_setn(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1441 SCErr meth_c_setn(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1443 sc_msg_iter msg(inSize, inData);
1445 float *data = inWorld->mControlBus;
1446 int32 *touched = inWorld->mControlBusTouched;
1447 int32 bufCounter = inWorld->mBufCounter;
1448 int maxIndex = inWorld->mNumControlBusChannels;
1450 while (msg.remain()) {
1451 int32 start = msg.geti();
1452 int32 n = msg.geti();
1453 int32 end = start+n-1;
1455 if (start < 0 || end >= maxIndex || start > end)
1456 return kSCErr_IndexOutOfRange;
1458 for (int i=start; msg.remain() && i<=end; ++i) {
1459 float32 value = msg.getf();
1460 data[i] = value;
1461 touched[i] = bufCounter;
1465 return kSCErr_None;
1469 SCErr meth_c_get(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1470 SCErr meth_c_get(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
1472 sc_msg_iter msg(inSize, inData);
1474 float *data = inWorld->mControlBus;
1475 uint32 maxIndex = inWorld->mNumControlBusChannels;
1477 int numheads = msg.remain() >> 2;
1479 big_scpacket packet;
1480 packet.adds("/c_set");
1481 packet.maketags(numheads * 2 + 1);
1482 packet.addtag(',');
1484 while (msg.remain() >= 4)
1486 uint32 index = msg.geti();
1487 if (index >= maxIndex)
1488 return kSCErr_IndexOutOfRange;
1489 packet.addtag('i');
1490 packet.addtag('f');
1491 packet.addi(index);
1492 packet.addf(data[index]);
1495 if (packet.size()) {
1496 CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
1499 return kSCErr_None;
1502 SCErr meth_c_getn(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1503 SCErr meth_c_getn(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
1505 sc_msg_iter msg(inSize, inData);
1507 float *data = inWorld->mControlBus;
1508 int maxIndex = inWorld->mNumControlBusChannels;
1510 // figure out how many tags to allocate
1511 int numcontrols = 0;
1512 int numheads = msg.remain() >> 3;
1514 while (msg.remain()) {
1515 msg.geti(); // skip start
1516 int32 n = msg.geti();
1517 numcontrols += n;
1520 big_scpacket packet;
1521 packet.adds("/c_setn");
1522 packet.maketags(numheads * 2 + numcontrols + 1);
1523 packet.addtag(',');
1525 // start over at beginning of message
1526 msg.init(inSize, inData);
1528 while (msg.remain()) {
1529 int32 start = msg.geti();
1530 int32 n = msg.geti();
1531 int32 end = start+n-1;
1533 if (start < 0 || end >= maxIndex || start > end)
1534 return kSCErr_IndexOutOfRange;
1536 packet.addtag('i');
1537 packet.addtag('i');
1538 packet.addi(start);
1539 packet.addi(n);
1541 for (int i=start; i<=end; ++i) {
1542 packet.addtag('f');
1543 packet.addf(data[i]);
1547 if (packet.size()) {
1548 CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
1551 return kSCErr_None;
1555 SCErr meth_c_fill(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1556 SCErr meth_c_fill(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1558 sc_msg_iter msg(inSize, inData);
1560 float *data = inWorld->mControlBus;
1561 int32 *touched = inWorld->mControlBusTouched;
1562 int32 bufCounter = inWorld->mBufCounter;
1563 int maxIndex = inWorld->mNumControlBusChannels;
1565 while (msg.remain() >= 12)
1567 int32 start = msg.geti();
1568 int32 n = msg.geti();
1569 float32 value = msg.getf();
1570 int32 end = start+n-1;
1572 if (end < 0 || start >= maxIndex) continue;
1574 start = sc_clip(start, 0, maxIndex-1);
1575 end = sc_clip(end, 0, maxIndex-1);
1577 for (int i=start; i<=end; ++i) {
1578 data[i] = value;
1579 touched[i] = bufCounter;
1583 return kSCErr_None;
1588 SCErr meth_b_get(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1589 SCErr meth_b_get(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
1591 sc_msg_iter msg(inSize, inData);
1592 int bufindex = msg.geti();
1593 SndBuf* buf = World_GetBuf(inWorld, bufindex);
1594 if (!buf) return kSCErr_Failed;
1596 float *data = buf->data;
1597 uint32 maxIndex = buf->samples;
1599 int numheads = msg.remain() >> 2;
1601 big_scpacket packet;
1602 packet.adds("/b_set");
1603 packet.maketags(numheads * 2 + 2);
1604 packet.addtag(',');
1605 packet.addtag('i');
1606 packet.addi(bufindex);
1608 while (msg.remain() >= 4)
1610 uint32 index = msg.geti();
1611 if (index >= maxIndex)
1612 return kSCErr_IndexOutOfRange;
1613 packet.addtag('i');
1614 packet.addtag('f');
1615 packet.addi(index);
1616 packet.addf(data[index]);
1619 if (packet.size()) {
1620 CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
1623 return kSCErr_None;
1626 SCErr meth_b_getn(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1627 SCErr meth_b_getn(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
1629 sc_msg_iter msg(inSize, inData);
1630 int bufindex = msg.geti();
1631 SndBuf* buf = World_GetBuf(inWorld, bufindex);
1632 if (!buf) return kSCErr_Failed;
1634 float *data = buf->data;
1635 int32 maxIndex = buf->samples;
1637 // figure out how many tags to allocate
1638 int numcontrols = 0;
1639 int numheads = msg.remain() >> 3;
1641 while (msg.remain()) {
1642 msg.geti(); // skip start
1643 int32 n = msg.geti();
1644 numcontrols += n;
1647 big_scpacket packet;
1648 packet.adds("/b_setn");
1649 packet.maketags(numheads * 2 + numcontrols + 2);
1650 packet.addtag(',');
1652 // start over at beginning of message
1653 msg.init(inSize, inData);
1654 msg.geti(); // skip buf index
1656 packet.addtag('i');
1657 packet.addi(bufindex);
1659 while (msg.remain()) {
1660 int32 start = msg.geti();
1661 int32 n = msg.geti();
1662 int32 end = start+n-1;
1664 if (start < 0 || end >= maxIndex || start > end)
1665 return kSCErr_IndexOutOfRange;
1667 packet.addtag('i');
1668 packet.addtag('i');
1669 packet.addi(start);
1670 packet.addi(n);
1672 for (int i=start; i<=end; ++i) {
1673 packet.addtag('f');
1674 packet.addf(data[i]);
1678 if (packet.size()) {
1679 CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
1682 return kSCErr_None;
1686 SCErr meth_s_get(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1687 SCErr meth_s_get(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
1689 sc_msg_iter msg(inSize, inData);
1691 Graph *graph = Msg_GetGraph(inWorld, msg);
1692 if (!graph) return kSCErr_NodeNotFound;
1694 int numheads = msg.tags ? strlen(msg.tags) - 1 : msg.remain() >> 2;
1696 big_scpacket packet;
1697 packet.adds("/n_set");
1698 packet.maketags(numheads * 2 + 2);
1699 packet.addtag(',');
1700 packet.addtag('i');
1701 packet.addi(graph->mNode.mID);
1703 while (msg.remain() >= 4) {
1704 if (msg.nextTag('i') == 's') {
1705 int32* name = msg.gets4();
1706 int32 hash = Hash(name);
1707 float32 value = 0.f;
1708 Graph_GetControl(graph, hash, name, 0, value);
1709 packet.addtag('s');
1710 packet.addtag('f');
1711 packet.adds((char*)name);
1712 packet.addf(value);
1713 } else {
1714 int32 index = msg.geti();
1715 float32 value = 0.f;
1716 Graph_GetControl(graph, index, value);
1717 packet.addtag('i');
1718 packet.addtag('f');
1719 packet.addi(index);
1720 packet.addf(value);
1724 if (packet.size()) {
1725 CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
1728 return kSCErr_None;
1731 SCErr meth_s_getn(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1732 SCErr meth_s_getn(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
1734 sc_msg_iter msg(inSize, inData);
1736 Graph *graph = Msg_GetGraph(inWorld, msg);
1737 if (!graph) return kSCErr_NodeNotFound;
1739 // figure out how many tags to allocate
1740 int numcontrols = 0;
1741 int numheads = msg.tags ? strlen(msg.tags) - 1 >> 1 : msg.remain() >> 3;
1743 while (msg.remain()) {
1744 msg.geti(); // skip start
1745 int32 n = msg.geti();
1746 numcontrols += n;
1749 big_scpacket packet;
1750 packet.adds("/n_setn");
1751 packet.maketags(numheads * 2 + numcontrols + 2);
1752 packet.addtag(',');
1754 // start over at beginning of message
1755 msg.init(inSize, inData);
1756 msg.geti(); // skip buf index
1758 packet.addtag('i');
1759 packet.addi(graph->mNode.mID);
1761 while (msg.remain()) {
1762 if (msg.nextTag('i') == 's') {
1763 int32* name = msg.gets4();
1764 int32 hash = Hash(name);
1765 int32 n = msg.geti();
1766 packet.addtag('s');
1767 packet.addtag('i');
1768 packet.adds((char*)name);
1769 packet.addi(n);
1770 for (int i=0; i<n; ++i) {
1771 float32 value = 0.f;
1772 Graph_GetControl(graph, hash, name, i, value);
1773 packet.addtag('f');
1774 packet.addf(value);
1776 } else {
1777 int32 index = msg.geti();
1778 int32 n = msg.geti();
1779 packet.addtag('i');
1780 packet.addtag('i');
1781 packet.addi(index);
1782 packet.addi(n);
1783 for (int i=0; i<n; ++i) {
1784 float32 value = 0.f;
1785 Graph_GetControl(graph, index+i, value);
1786 packet.addtag('f');
1787 packet.addf(value);
1792 if (packet.size()) {
1793 CallSequencedCommand(SendReplyCmd, inWorld, packet.size(), packet.data(), inReply);
1796 return kSCErr_None;
1801 SCErr meth_s_noid(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1802 SCErr meth_s_noid(World *inWorld, int inSize, char *inData, ReplyAddress* inReply)
1804 sc_msg_iter msg(inSize, inData);
1805 while (msg.remain()) {
1807 Graph *graph = Msg_GetGraph(inWorld, msg);
1808 if (!graph) continue;
1810 Graph_RemoveID(inWorld, graph);
1813 return kSCErr_None;
1817 SCErr meth_notify(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1818 SCErr meth_notify(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
1820 CallSequencedCommand(NotifyCmd, inWorld, inSize, inData, inReply);
1821 return kSCErr_None;
1824 SCErr meth_error(World *inWorld, int inSize, char *inData, ReplyAddress *inReply);
1825 SCErr meth_error(World *inWorld, int inSize, char *inData, ReplyAddress* /*inReply*/)
1827 sc_msg_iter msg(inSize, inData);
1828 int mode = msg.geti();
1830 // inWorld->mLocalErrorNotification = mode;
1831 // // if non-zero, new state should be saved permanently
1832 // if(mode) { inWorld->mErrorNotification = mode; };
1834 // -1 = bundle off, -2 = bundle on, 0 = permanent off, 1 = permanent on
1835 switch(mode) {
1836 case -1: inWorld->mLocalErrorNotification += 1;
1837 break;
1838 case -2: inWorld->mLocalErrorNotification -= 1;
1839 break;
1840 case 0: inWorld->mErrorNotification = 0;
1841 break;
1842 case 1: inWorld->mErrorNotification = 1;
1844 return kSCErr_None;
1847 #define NEW_COMMAND(name) NewCommand(#name, cmd_##name, meth_##name)
1849 void initMiscCommands();
1850 void initMiscCommands()
1853 // nrt
1854 NEW_COMMAND(none);
1855 NEW_COMMAND(notify);
1856 NEW_COMMAND(status);
1857 NEW_COMMAND(quit);
1858 NEW_COMMAND(clearSched);
1860 NEW_COMMAND(d_recv);
1861 NEW_COMMAND(d_load);
1862 NEW_COMMAND(d_loadDir);
1863 NEW_COMMAND(d_freeAll);
1864 NEW_COMMAND(d_free);
1866 NEW_COMMAND(s_new);
1867 NEW_COMMAND(s_newargs);
1869 NEW_COMMAND(n_trace);
1870 NEW_COMMAND(n_free);
1871 NEW_COMMAND(n_run);
1873 NEW_COMMAND(u_cmd);
1874 NEW_COMMAND(cmd);
1876 //NEW_COMMAND(n_cmd);
1877 NEW_COMMAND(n_map);
1878 NEW_COMMAND(n_mapn);
1879 NEW_COMMAND(n_mapa);
1880 NEW_COMMAND(n_mapan);
1881 NEW_COMMAND(n_set);
1882 NEW_COMMAND(n_setn);
1883 NEW_COMMAND(n_fill);
1885 NEW_COMMAND(n_before);
1886 NEW_COMMAND(n_after);
1887 NEW_COMMAND(n_order);
1889 NEW_COMMAND(g_new);
1890 NEW_COMMAND(g_head);
1891 NEW_COMMAND(g_tail);
1892 NEW_COMMAND(g_freeAll);
1893 NEW_COMMAND(g_deepFree);
1895 NEW_COMMAND(p_new);
1897 NEW_COMMAND(b_alloc);
1898 NEW_COMMAND(b_allocRead);
1899 NEW_COMMAND(b_allocReadChannel);
1901 NEW_COMMAND(b_read);
1902 NEW_COMMAND(b_readChannel);
1903 NEW_COMMAND(b_write);
1905 NEW_COMMAND(b_free);
1906 NEW_COMMAND(b_close);
1908 NEW_COMMAND(b_zero);
1909 NEW_COMMAND(b_set);
1910 NEW_COMMAND(b_setn);
1911 NEW_COMMAND(b_fill);
1912 NEW_COMMAND(b_gen);
1914 NEW_COMMAND(c_set);
1915 NEW_COMMAND(c_setn);
1916 NEW_COMMAND(c_fill);
1918 NEW_COMMAND(dumpOSC);
1920 NEW_COMMAND(c_get);
1921 NEW_COMMAND(c_getn);
1922 NEW_COMMAND(b_get);
1923 NEW_COMMAND(b_getn);
1924 NEW_COMMAND(s_get);
1925 NEW_COMMAND(s_getn);
1927 NEW_COMMAND(n_query);
1928 NEW_COMMAND(b_query);
1930 NEW_COMMAND(s_noid);
1931 NEW_COMMAND(sync);
1932 NEW_COMMAND(g_dumpTree);
1933 NEW_COMMAND(g_queryTree);
1935 NEW_COMMAND(error);