*** empty log message ***
[chuck-blob.git] / v2 / ulib_opsc.cpp
blob1f4cc01a747b51699b7199e8e1761c1d33f745a9
1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: ulib_opsc.cpp
27 // desc: ...
29 // author: Philip L. Davidson (philipd@alumni.princeton.edu)
30 // Ge Wang (gewang@cs.princeton.edu)
31 // Perry R. Cook (prc@cs.princeton.edu)
32 // date: Spring 2005
33 //-----------------------------------------------------------------------------
34 #include "ulib_opsc.h"
35 #include "chuck_type.h"
36 #include "chuck_vm.h"
37 #include "chuck_dl.h"
38 #include "util_opsc.h"
39 #include "chuck_instr.h"
41 static t_CKUINT osc_send_offset_data = 0;
42 static t_CKUINT osc_recv_offset_data = 0;
43 static t_CKUINT osc_address_offset_data = 0;
44 static Chuck_Type * osc_addr_type_ptr = 0;
46 DLL_QUERY opensoundcontrol_query ( Chuck_DL_Query * query ) {
48 // get the env
49 Chuck_Env * env = Chuck_Env::instance();
50 Chuck_DL_Func * func = NULL;
52 // init base class
53 if( !type_engine_import_class_begin( env, "OscSend", "Object",
54 env->global(), osc_send_ctor,
55 osc_send_dtor ) )
56 return FALSE;
58 // add member variable - OSCTransmitter object
59 osc_send_offset_data = type_engine_import_mvar( env, "int", "@OscSend_data", FALSE );
60 if( osc_send_offset_data == CK_INVALID_OFFSET ) goto error;
62 func = make_new_mfun( "int", "setHost", osc_send_setHost );
63 func->add_arg( "string", "address" );
64 func->add_arg( "int", "port" );
65 if( !type_engine_import_mfun( env, func ) ) goto error;
67 func = make_new_mfun( "int", "startMsg", osc_send_startMesg );
68 func->add_arg( "string", "address" );
69 func->add_arg( "string", "args" );
70 if( !type_engine_import_mfun( env, func ) ) goto error;
72 func = make_new_mfun( "int", "startMsg", osc_send_startMesg_spec );
73 func->add_arg( "string", "spec" );
74 if( !type_engine_import_mfun( env, func ) ) goto error;
76 func = make_new_mfun( "int", "addInt", osc_send_addInt );
77 func->add_arg( "int", "value" );
78 if( !type_engine_import_mfun( env, func ) ) goto error;
80 func = make_new_mfun( "float", "addFloat", osc_send_addFloat );
81 func->add_arg( "float", "value" );
82 if( !type_engine_import_mfun( env, func ) ) goto error;
84 func = make_new_mfun( "string", "addString", osc_send_addString );
85 func->add_arg( "string", "value" );
86 if( !type_engine_import_mfun( env, func ) ) goto error;
88 func = make_new_mfun( "int", "openBundle", osc_send_openBundle );
89 func->add_arg( "time", "value" );
90 if( !type_engine_import_mfun( env, func ) ) goto error;
92 func = make_new_mfun( "int", "closeBundle", osc_send_closeBundle );
93 if( !type_engine_import_mfun( env, func ) ) goto error;
95 func = make_new_mfun( "int", "hold", osc_send_holdMesg );
96 func->add_arg( "int", "on" );
97 if( !type_engine_import_mfun( env, func ) ) goto error;
99 func = make_new_mfun( "int", "kick", osc_send_kickMesg );
100 if( !type_engine_import_mfun( env, func ) ) goto error;
102 type_engine_import_class_end( env );
104 // init base class
105 if( !type_engine_import_class_begin( env, "OscEvent", "Event",
106 env->global(), osc_address_ctor,
107 osc_address_dtor ) )
108 return FALSE;
110 // add member variable - OSCAddress object
112 osc_address_offset_data = type_engine_import_mvar( env, "int", "@OscEvent_Data", FALSE );
113 if( osc_recv_offset_data == CK_INVALID_OFFSET ) goto error;
115 // keep type around for initialization ( so other classes can return it )
117 osc_addr_type_ptr = env->class_def;
119 func = make_new_mfun( "int", "set", osc_address_set );
120 func->add_arg( "string" , "addr" );
121 if( !type_engine_import_mfun( env, func ) ) goto error;
123 func = make_new_mfun( "int", "hasMsg", osc_address_has_mesg );
124 if( !type_engine_import_mfun( env, func ) ) goto error;
126 func = make_new_mfun( "int", "nextMsg", osc_address_next_mesg );
127 if( !type_engine_import_mfun( env, func ) ) goto error;
129 func = make_new_mfun( "int", "getInt", osc_address_next_int );
130 if( !type_engine_import_mfun( env, func ) ) goto error;
132 func = make_new_mfun( "float", "getFloat", osc_address_next_float );
133 if( !type_engine_import_mfun( env, func ) ) goto error;
135 func = make_new_mfun( "string", "getString", osc_address_next_string );
136 if( !type_engine_import_mfun( env, func ) ) goto error;
138 func = make_new_mfun( "int", "can_wait", osc_address_can_wait );
139 if( !type_engine_import_mfun( env, func ) ) goto error;
141 type_engine_import_class_end( env );
143 // init base class
144 if( !type_engine_import_class_begin( env, "OscRecv", "Object",
145 env->global(), osc_recv_ctor,
146 osc_recv_dtor ) )
147 return FALSE;
149 // add member variable - OSCReceiver object
150 osc_recv_offset_data = type_engine_import_mvar( env, "int", "@OscRecv_data", FALSE );
151 if( osc_recv_offset_data == CK_INVALID_OFFSET ) goto error;
153 func = make_new_mfun( "int", "port", osc_recv_port );
154 func->add_arg( "int" , "port" );
155 if( !type_engine_import_mfun( env, func ) ) goto error;
157 func = make_new_mfun( "int", "listen", osc_recv_listen_port );
158 func->add_arg( "int" , "port" );
159 if( !type_engine_import_mfun( env, func ) ) goto error;
161 func = make_new_mfun( "int", "listen", osc_recv_listen );
162 if( !type_engine_import_mfun( env, func ) ) goto error;
164 func = make_new_mfun( "int", "stop", osc_recv_listen_stop );
165 if( !type_engine_import_mfun( env, func ) ) goto error;
167 func = make_new_mfun( "int", "add_address", osc_recv_add_address );
168 func->add_arg( "OscEvent" , "addr" );
169 if( !type_engine_import_mfun( env, func ) ) goto error;
171 func = make_new_mfun( "int", "remove_address", osc_recv_remove_address );
172 func->add_arg( "OscEvent" , "addr" );
173 if( !type_engine_import_mfun( env, func ) ) goto error;
175 func = make_new_mfun( "OscEvent", "event", osc_recv_new_address );
176 func->add_arg( "string" , "spec" );
177 if( !type_engine_import_mfun( env, func ) ) goto error;
179 func = make_new_mfun( "OscEvent", "event", osc_recv_new_address_type );
180 func->add_arg( "string" , "address" );
181 func->add_arg( "string" , "type" );
182 if( !type_engine_import_mfun( env, func ) ) goto error;
184 func = make_new_mfun( "OscEvent", "address", osc_recv_new_address );
185 func->add_arg( "string" , "spec" );
186 if( !type_engine_import_mfun( env, func ) ) goto error;
188 func = make_new_mfun( "OscEvent", "address", osc_recv_new_address_type );
189 func->add_arg( "string" , "address" );
190 func->add_arg( "string" , "type" );
191 if( !type_engine_import_mfun( env, func ) ) goto error;
193 type_engine_import_class_end( env );
194 return TRUE;
196 error:
198 fprintf( stderr, "class import error!\n" );
199 // end the class import
200 type_engine_import_class_end( env );
201 return FALSE;
204 //----------------------------------------------
205 // name : osc_send_ctor
206 // desc : CTOR function
207 //-----------------------------------------------
208 CK_DLL_CTOR( osc_send_ctor ) {
209 OSC_Transmitter* xmit = new OSC_Transmitter();
210 OBJ_MEMBER_INT( SELF, osc_send_offset_data ) = (t_CKINT)xmit;
213 //----------------------------------------------
214 // name : osc_send_dtor
215 // desc : DTOR function
216 //-----------------------------------------------
217 CK_DLL_DTOR( osc_send_dtor ) {
218 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
219 SAFE_DELETE(xmit);
220 OBJ_MEMBER_UINT(SELF, osc_send_offset_data) = 0;
223 //----------------------------------------------
224 // name : osc_send_setHost
225 // desc : MFUN function
226 //-----------------------------------------------
227 CK_DLL_MFUN( osc_send_setHost ) {
228 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
229 Chuck_String* host = GET_NEXT_STRING(ARGS);
230 t_CKINT port = GET_NEXT_INT(ARGS);
231 xmit->setHost( (char*) host->str.c_str(), port );
234 //----------------------------------------------
235 // name : osc_send_startMesg
236 // desc : MFUN function
237 //-----------------------------------------------
238 CK_DLL_MFUN( osc_send_startMesg ) {
239 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
240 Chuck_String* address = GET_NEXT_STRING(ARGS);
241 Chuck_String* args = GET_NEXT_STRING(ARGS);
242 xmit->startMessage( (char*) address->str.c_str(), (char*) args->str.c_str() );
245 //----------------------------------------------
246 // name : osc_send_startMesg
247 // desc : MFUN function
248 //-----------------------------------------------
249 CK_DLL_MFUN( osc_send_startMesg_spec ) {
250 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
251 Chuck_String* spec = GET_NEXT_STRING(ARGS);
252 xmit->startMessage( (char*) spec->str.c_str() );
255 //----------------------------------------------
256 // name : osc_send_addInt
257 // desc : MFUN function
258 //-----------------------------------------------
259 CK_DLL_MFUN( osc_send_addInt ) {
260 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
261 xmit->addInt( GET_NEXT_INT(ARGS) );
264 //----------------------------------------------
265 // name : osc_send_addFloat
266 // desc : MFUN function
267 //-----------------------------------------------
268 CK_DLL_MFUN( osc_send_addFloat ) {
269 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
270 xmit->addFloat( (float)(GET_NEXT_FLOAT(ARGS)) );
273 //----------------------------------------------
274 // name : osc_send_addString
275 // desc : MFUN function
276 //-----------------------------------------------
277 CK_DLL_MFUN( osc_send_addString ) {
278 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
279 xmit->addString( (char*)(GET_NEXT_STRING(ARGS))->str.c_str() );
282 //----------------------------------------------
283 // name : osc_send_openBundle
284 // desc : MFUN function
285 //-----------------------------------------------
286 CK_DLL_MFUN( osc_send_openBundle ) {
287 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
288 // we should add in an option to translate from chuck-time to current time to timetag.
289 // but for now let's just spec. immediately.
290 xmit->openBundle(OSCTT_Immediately());
293 //----------------------------------------------
294 // name : osc_send_closeBundle
295 // desc : MFUN function
296 //-----------------------------------------------
297 CK_DLL_MFUN( osc_send_closeBundle ) {
298 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
299 xmit->closeBundle();
302 //----------------------------------------------
303 // name : osc_send_holdMesg
304 // desc : MFUN function
305 //-----------------------------------------------
306 CK_DLL_MFUN( osc_send_holdMesg ) {
307 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
308 xmit->holdMessage( GET_NEXT_INT(ARGS) != 0 );
311 //----------------------------------------------
312 // name : osc_send_kickMesg
313 // desc : MFUN function
314 //-----------------------------------------------
315 CK_DLL_MFUN( osc_send_kickMesg ) {
316 OSC_Transmitter* xmit = (OSC_Transmitter *)OBJ_MEMBER_INT(SELF, osc_send_offset_data);
317 xmit->kickMessage();
320 //----------------------------------------------
321 // name : osc_address_ctor
322 // desc : CTOR function
323 //-----------------------------------------------
324 CK_DLL_CTOR( osc_address_ctor ) {
325 OSC_Address_Space * addr = new OSC_Address_Space();
326 addr->SELF = SELF;
327 // fprintf(stderr,"address:ptr %x\n", (uint)addr);
328 // fprintf(stderr,"self:ptr %x\n", (uint)SELF);
329 OBJ_MEMBER_INT(SELF, osc_address_offset_data) = (t_CKINT)addr;
332 CK_DLL_DTOR( osc_address_dtor ) {
333 delete (OSC_Address_Space *)OBJ_MEMBER_UINT(SELF, osc_address_offset_data);
334 OBJ_MEMBER_UINT(SELF, osc_address_offset_data) = 0;
337 CK_DLL_MFUN( osc_address_set ) {
338 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( SELF, osc_address_offset_data );
339 addr->setSpec ( (char*)(GET_NEXT_STRING(ARGS))->str.c_str() );
340 RETURN->v_int = 0;
343 //----------------------------------------------
344 // name : osc_address_can_wait
345 // desc : MFUN function
346 //-----------------------------------------------
347 CK_DLL_MFUN( osc_address_can_wait ) {
348 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( SELF, osc_address_offset_data );
349 RETURN->v_int = ( addr->has_mesg() ) ? 0 : 1;
352 //----------------------------------------------
353 // name : osc_address_has_mesg
354 // desc : MFUN function
355 //-----------------------------------------------
356 CK_DLL_MFUN( osc_address_has_mesg ) {
357 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( SELF, osc_address_offset_data );
358 RETURN->v_int = ( addr->has_mesg() ) ? 1 : 0 ;
361 //----------------------------------------------
362 // name : osc_address_next_mesg
363 // desc : MFUN function
364 //-----------------------------------------------
365 CK_DLL_MFUN( osc_address_next_mesg ) {
366 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( SELF, osc_address_offset_data );
367 RETURN->v_int = ( addr->next_mesg() ) ? 1 : 0 ;
370 //----------------------------------------------
371 // name : osc_address_next_int
372 // desc : MFUN function
373 //-----------------------------------------------
374 CK_DLL_MFUN( osc_address_next_int ) {
375 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( SELF, osc_address_offset_data );
376 RETURN->v_int = addr->next_int();
379 //----------------------------------------------
380 // name : osc_address_next_float
381 // desc : MFUN function
382 //-----------------------------------------------
383 CK_DLL_MFUN( osc_address_next_float ) {
384 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( SELF, osc_address_offset_data );
385 RETURN->v_float = addr->next_float();
388 //----------------------------------------------
389 // name : osc_address_next_string
390 // desc : MFUN function
391 //-----------------------------------------------
392 CK_DLL_MFUN( osc_address_next_string ) {
393 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( SELF, osc_address_offset_data );
394 char * cs = addr->next_string();
395 Chuck_String * ckstr = ( cs ) ? new Chuck_String ( cs ) : new Chuck_String("");
396 initialize_object( ckstr, &t_string );
397 RETURN->v_string = ckstr;
400 // OscRecv functions
403 //----------------------------------------------
404 // name : osc_recv_ctor
405 // desc : CTOR function
406 //-----------------------------------------------
407 CK_DLL_CTOR( osc_recv_ctor ) {
408 OSC_Receiver * recv = new OSC_Receiver();
409 OBJ_MEMBER_INT( SELF, osc_send_offset_data ) = (t_CKINT)recv;
412 //----------------------------------------------
413 // name : osc_recv_dtor
414 // desc : DTOR function
415 //-----------------------------------------------
416 CK_DLL_DTOR( osc_recv_dtor ) {
417 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
418 SAFE_DELETE(recv);
419 OBJ_MEMBER_INT(SELF, osc_recv_offset_data) = 0;
422 //----------------------------------------------
423 // name : osc_recv_port
424 // desc : specify port to listen on
425 //-----------------------------------------------
426 CK_DLL_MFUN( osc_recv_port ) {
428 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
429 recv->bind_to_port( (int)GET_NEXT_INT(ARGS) );
432 // need to add a listen function in Receiver which opens up a recv loop on another thread.
433 // address then subscribe to a receiver to take in events.
435 //----------------------------------------------
436 // name : osc_recv_listen
437 // desc : start listening
438 //-----------------------------------------------
439 CK_DLL_MFUN( osc_recv_listen ) {
440 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
441 recv->listen();
444 //----------------------------------------------
445 // name : osc_recv_listen_port
446 // desc : listen to a given port ( disconnects from current )
447 //-----------------------------------------------
448 CK_DLL_MFUN( osc_recv_listen_port ) {
449 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
450 recv->listen((int)GET_NEXT_INT(ARGS));
453 //----------------------------------------------
454 // name : osc_recv_listen_port
455 // desc : listen to a given port ( disconnects from current )
456 //-----------------------------------------------
457 CK_DLL_MFUN( osc_recv_listen_stop ) {
458 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
459 recv->stopListening();
462 //----------------------------------------------
463 // name : osc_recv_add_listener
464 // desc : MFUN function
465 //-----------------------------------------------
466 CK_DLL_MFUN( osc_recv_add_address ) {
467 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
468 Chuck_Object* addr_obj = GET_NEXT_OBJECT(ARGS); //address object class...
469 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( addr_obj, osc_address_offset_data );
470 recv->add_address( addr );
473 //----------------------------------------------
474 // name : osc_recv_remove_listener
475 // desc : MFUN function
476 //-----------------------------------------------
477 CK_DLL_MFUN( osc_recv_remove_address ) {
478 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
479 Chuck_Object* addr_obj = GET_NEXT_OBJECT(ARGS); //listener object class...
480 OSC_Address_Space * addr = (OSC_Address_Space *)OBJ_MEMBER_INT( addr_obj, osc_address_offset_data );
481 recv->remove_address( addr );
484 //----------------------------------------------
485 // name : osc_recv_new_address
486 // desc : MFUN function
487 //-----------------------------------------------
488 CK_DLL_MFUN( osc_recv_new_address ) {
489 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
490 Chuck_String* spec_obj = (Chuck_String*) GET_NEXT_STRING(ARGS); //listener object class...
492 OSC_Address_Space* new_addr_obj = recv->new_event ( (char*)spec_obj->str.c_str() );
494 /* wolf in sheep's clothing
495 initialize_object( new_addr_obj , osc_addr_type_ptr ); //initialize in vm
496 new_addr_obj->SELF = new_addr_obj;
497 OBJ_MEMBER_INT( new_addr_obj, osc_address_offset_data ) = (t_CKINT)new_addr_obj;
500 // more correct...?
501 Chuck_Event* new_event_obj = new Chuck_Event();
502 initialize_object( new_event_obj, osc_addr_type_ptr );
503 new_addr_obj->SELF = new_event_obj;
504 OBJ_MEMBER_INT( new_event_obj, osc_address_offset_data ) = (t_CKINT)new_addr_obj;
506 RETURN->v_object = new_event_obj;
511 //----------------------------------------------
512 // name : osc_recv_new_address
513 // desc : MFUN function
514 //-----------------------------------------------
515 CK_DLL_MFUN( osc_recv_new_address_type ) {
516 OSC_Receiver * recv = (OSC_Receiver *)OBJ_MEMBER_INT(SELF, osc_recv_offset_data);
517 Chuck_String* addr_obj = (Chuck_String*) GET_NEXT_STRING(ARGS); //listener object class...
518 Chuck_String* type_obj = (Chuck_String*) GET_NEXT_STRING(ARGS); //listener object class...
520 OSC_Address_Space* new_addr_obj = recv->new_event ( (char*)addr_obj->str.c_str(), (char*)type_obj->str.c_str() );
522 /* wolf in sheep's clothing
523 initialize_object( new_addr_obj , osc_addr_type_ptr ); //initialize in vm
524 new_addr_obj->SELF = new_addr_obj;
525 OBJ_MEMBER_INT( new_addr_obj, osc_address_offset_data ) = (t_CKINT)new_addr_obj;
528 // more correct...?
529 Chuck_Event* new_event_obj = new Chuck_Event();
530 initialize_object( new_event_obj, osc_addr_type_ptr );
531 new_addr_obj->SELF = new_event_obj;
532 OBJ_MEMBER_INT( new_event_obj, osc_address_offset_data ) = (t_CKINT)new_addr_obj;
534 RETURN->v_object = new_event_obj;