*** empty log message ***
[chuck-blob.git] / v2 / chuck_vm.h
blobb6257b6cd6555f5520feb06242f8ffe0b3d8ce99
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: chuck_vm.h
27 // desc: ...
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 // date: Autumn 2002
32 //-----------------------------------------------------------------------------
33 #ifndef __CHUCK_VM_H__
34 #define __CHUCK_VM_H__
36 #include "chuck_oo.h"
37 #include "chuck_ugen.h"
39 // tracking
40 #ifdef __CHUCK_STAT_TRACK__
41 #include "chuck_stats.h"
42 #endif
44 #include <string>
45 #include <map>
46 #include <vector>
51 //-----------------------------------------------------------------------------
52 // vm defines
53 //-----------------------------------------------------------------------------
54 #define CVM_MEM_STACK_SIZE (0x1 << 16)
55 #define CVM_REG_STACK_SIZE (0x1 << 14)
58 // forward references
59 struct Chuck_Instr;
60 struct Chuck_VM;
61 struct Chuck_VM_Func;
62 struct Chuck_VM_FTable;
63 struct Chuck_Msg;
65 class BBQ;
66 class CBufferSimple;
67 class Digitalio;
72 //-----------------------------------------------------------------------------
73 // name: struct Chuck_VM_Stack
74 // desc: ...
75 //-----------------------------------------------------------------------------
76 struct Chuck_VM_Stack
78 //-----------------------------------------------------------------------------
79 // functions
80 //-----------------------------------------------------------------------------
81 public:
82 Chuck_VM_Stack();
83 ~Chuck_VM_Stack();
85 public:
86 t_CKBOOL initialize( t_CKUINT size );
87 t_CKBOOL shutdown();
89 //-----------------------------------------------------------------------------
90 // data
91 //-----------------------------------------------------------------------------
92 public: // machine
93 t_CKBYTE * stack;
94 t_CKBYTE * sp;
95 t_CKBYTE * sp_max;
97 public: // linked list
98 Chuck_VM_Stack * prev;
99 Chuck_VM_Stack * next;
101 public: // state
102 t_CKBOOL m_is_init;
108 //-----------------------------------------------------------------------------
109 // name: struct Chuck_VM_Code
110 // desc: ...
111 //-----------------------------------------------------------------------------
112 struct Chuck_VM_Code : Chuck_Object
114 public:
115 Chuck_VM_Code();
116 ~Chuck_VM_Code();
118 public:
119 // array of Chuck_Instr *, should always end with Chuck_Instr_EOF
120 Chuck_Instr ** instr;
121 // size of the array
122 t_CKUINT num_instr;
124 // name of this code
125 std::string name;
126 // the depth of any function arguments
127 t_CKUINT stack_depth;
128 // whether the function needs 'this' pointer or not
129 t_CKBOOL need_this;
130 // native
131 t_CKUINT native_func;
132 // is ctor?
133 t_CKUINT native_func_type;
135 // native func types
136 enum { NATIVE_UNKNOWN, NATIVE_CTOR, NATIVE_DTOR, NATIVE_MFUN, NATIVE_SFUN };
142 //-----------------------------------------------------------------------------
143 // name: struct Chuck_VM_Shred
144 // desc: ...
145 //-----------------------------------------------------------------------------
146 struct Chuck_VM_Shred : Chuck_Object
148 //-----------------------------------------------------------------------------
149 // functions
150 //-----------------------------------------------------------------------------
151 public:
152 Chuck_VM_Shred( );
153 ~Chuck_VM_Shred( );
155 t_CKBOOL initialize( Chuck_VM_Code * c,
156 t_CKUINT mem_st_size = CVM_MEM_STACK_SIZE,
157 t_CKUINT reg_st_size = CVM_REG_STACK_SIZE );
158 t_CKBOOL shutdown();
159 t_CKBOOL run( Chuck_VM * vm );
160 t_CKBOOL add( Chuck_UGen * ugen );
161 t_CKBOOL remove( Chuck_UGen * ugen );
163 //-----------------------------------------------------------------------------
164 // data
165 //-----------------------------------------------------------------------------
166 public: // machine components
167 // stacks
168 Chuck_VM_Stack * mem;
169 Chuck_VM_Stack * reg;
171 // ref to base stack - if this is the root, then base is mem
172 Chuck_VM_Stack * base_ref;
174 // code
175 Chuck_VM_Code * code;
176 Chuck_VM_Code * code_orig; // the one to release
177 Chuck_Instr ** instr;
178 Chuck_VM_Shred * parent;
179 std::map<t_CKUINT, Chuck_VM_Shred *> children;
180 t_CKUINT pc;
182 // vm
183 Chuck_VM * vm_ref;
185 // time
186 t_CKTIME now;
187 t_CKTIME start;
189 // state (no longer needed, see array_alloc)
190 // t_CKUINT * obj_array;
191 // t_CKUINT obj_array_size;
193 public:
194 t_CKTIME wake_time;
195 t_CKUINT next_pc;
196 t_CKBOOL is_done;
197 t_CKBOOL is_running;
198 t_CKBOOL is_abort;
199 t_CKBOOL is_dumped;
200 Chuck_Event * event; // event shred is waiting on
201 std::map<Chuck_UGen *, Chuck_UGen *> m_ugen_map;
203 public: // id
204 t_CKUINT xid;
205 std::string name;
206 std::vector<std::string> args;
208 public:
209 Chuck_VM_Shred * prev;
210 Chuck_VM_Shred * next;
212 // tracking
213 CK_TRACK( Shred_Stat * stat );
219 //-----------------------------------------------------------------------------
220 // name: struct Chuck_VM_Shred_Status
221 // desc: ...
222 //-----------------------------------------------------------------------------
223 struct Chuck_VM_Shred_Status : Chuck_Object
225 public:
226 t_CKUINT xid;
227 std::string name;
228 t_CKTIME start;
229 t_CKBOOL has_event;
231 public:
232 Chuck_VM_Shred_Status( t_CKUINT _id, const std::string & n, t_CKTIME _start, t_CKBOOL e )
234 xid = _id;
235 name = n;
236 start = _start;
237 has_event = e;
244 //-----------------------------------------------------------------------------
245 // name: struct Chuck_VM_Status
246 // desc: ...
247 //-----------------------------------------------------------------------------
248 struct Chuck_VM_Status : Chuck_Object
250 public:
251 Chuck_VM_Status();
252 ~Chuck_VM_Status();
253 void clear();
255 public:
256 // sample rate
257 t_CKUINT srate;
258 // now
259 t_CKTIME now_system;
260 // for display
261 t_CKUINT t_second;
262 t_CKUINT t_minute;
263 t_CKUINT t_hour;
264 // list of shred status
265 std::vector<Chuck_VM_Shred_Status *> list;
271 //-----------------------------------------------------------------------------
272 // name: struct Chuck_VM_Shreduler
273 // desc: ...
274 //-----------------------------------------------------------------------------
275 struct Chuck_VM_Shreduler : Chuck_Object
277 //-----------------------------------------------------------------------------
278 // functions
279 //-----------------------------------------------------------------------------
280 public:
281 Chuck_VM_Shreduler();
282 ~Chuck_VM_Shreduler();
284 public:
285 t_CKBOOL initialize();
286 t_CKBOOL shutdown();
288 public: // shreduling
289 t_CKBOOL shredule( Chuck_VM_Shred * shred );
290 t_CKBOOL shredule( Chuck_VM_Shred * shred, t_CKTIME wake_time );
291 Chuck_VM_Shred * get( );
292 void advance( );
293 void advance2( );
295 public: // high-level shred interface
296 t_CKBOOL remove( Chuck_VM_Shred * shred );
297 t_CKBOOL replace( Chuck_VM_Shred * out, Chuck_VM_Shred * in );
298 Chuck_VM_Shred * lookup( t_CKUINT xid );
299 void status( );
300 void status( Chuck_VM_Status * status );
301 t_CKUINT highest();
303 public: // for event related shred queue
304 t_CKBOOL add_blocked( Chuck_VM_Shred * shred );
305 t_CKBOOL remove_blocked( Chuck_VM_Shred * shred );
307 //-----------------------------------------------------------------------------
308 // data
309 //-----------------------------------------------------------------------------
310 public:
311 // time and audio
312 t_CKTIME now_system;
313 t_CKBOOL rt_audio;
314 BBQ * bbq;
316 // shreds to be shreduled
317 Chuck_VM_Shred * shred_list;
318 // shreds waiting on events
319 std::map<Chuck_VM_Shred *, Chuck_VM_Shred *> blocked;
320 // current shred
321 Chuck_VM_Shred * m_current_shred; // TODO: ref count?
323 // ugen
324 Chuck_UGen * m_dac;
325 Chuck_UGen * m_adc;
326 Chuck_UGen * m_bunghole;
327 t_CKUINT m_num_dac_channels;
328 t_CKUINT m_num_adc_channels;
330 // status cache
331 Chuck_VM_Status m_status;
337 //-----------------------------------------------------------------------------
338 // name: struct Chuck_VM
339 // desc: ...
340 //-----------------------------------------------------------------------------
341 struct Chuck_VM : Chuck_Object
343 //-----------------------------------------------------------------------------
344 // functions
345 //-----------------------------------------------------------------------------
346 public:
347 Chuck_VM();
348 ~Chuck_VM();
350 public: // init
351 t_CKBOOL initialize( t_CKBOOL enable_audio = TRUE, t_CKBOOL halt = TRUE,
352 t_CKUINT srate = 44100,
353 t_CKUINT buffer_size = 512, t_CKUINT num_buffers = 4,
354 t_CKUINT dac = 0, t_CKUINT adc = 0,
355 t_CKUINT dac_chan = 2, t_CKUINT adc_chan = 2,
356 t_CKBOOL block = TRUE );
357 t_CKBOOL initialize_synthesis( );
358 t_CKBOOL shutdown();
360 public: // shreds
361 Chuck_VM_Shred * spork( Chuck_VM_Code * code, Chuck_VM_Shred * parent );
362 Chuck_VM_Shred * fork( Chuck_VM_Code * code );
363 Chuck_VM_Shreduler * shreduler() const;
364 t_CKUINT next_id( );
366 public: // audio
367 BBQ * bbq() const;
368 t_CKUINT srate() const;
369 void compensate_bbq();
371 public: // running the machine
372 t_CKBOOL run( );
373 t_CKBOOL run( t_CKINT num_samps );
374 t_CKBOOL compute( );
375 t_CKBOOL pause( );
376 t_CKBOOL stop( );
377 t_CKBOOL start_audio( );
378 t_CKBOOL abort_current_shred( );
380 public: // invoke functions
381 t_CKBOOL invoke_static( Chuck_VM_Shred * shred );
383 public: // garbage collection
384 void gc();
385 void gc( t_CKUINT amount );
387 public: // msg
388 t_CKBOOL queue_msg( Chuck_Msg * msg, int num_msg );
389 t_CKBOOL queue_event( Chuck_Event * event, int num_msg );
390 t_CKUINT process_msg( Chuck_Msg * msg );
391 Chuck_Msg * get_reply( );
393 public: // static/dynamic function table
394 //void set_env( void * env ) { m_env = env; }
395 //void * get_env( ) { return m_env; }
396 t_CKBOOL has_init() { return m_init; }
397 t_CKBOOL is_running() { return m_running; }
399 public: // get error
400 const char * last_error() const
401 { return m_last_error.c_str(); }
403 //-----------------------------------------------------------------------------
404 // data
405 //-----------------------------------------------------------------------------
406 public:
407 // ugen
408 Chuck_UGen * m_adc;
409 Chuck_UGen * m_dac;
410 Chuck_UGen * m_bunghole;
411 t_CKUINT m_num_adc_channels;
412 t_CKUINT m_num_dac_channels;
414 t_CKBOOL m_halt;
415 t_CKBOOL m_audio;
416 t_CKBOOL m_block;
418 protected:
419 Chuck_VM_Shred * spork( Chuck_VM_Shred * shred );
420 t_CKBOOL free( Chuck_VM_Shred * shred, t_CKBOOL cascade,
421 t_CKBOOL dec = TRUE );
422 void dump( Chuck_VM_Shred * shred );
423 void release_dump();
425 protected:
426 t_CKBOOL m_init;
427 // t_CKBOOL m_running; -> moved to public
428 t_CKBOOL m_audio_started;
429 std::string m_last_error;
431 // shred
432 Chuck_VM_Shred * m_shreds;
433 t_CKUINT m_num_shreds;
434 t_CKUINT m_shred_id;
435 Chuck_VM_Shreduler * m_shreduler;
436 // place to put dumped shreds
437 std::vector<Chuck_VM_Shred *> m_shred_dump;
438 t_CKUINT m_num_dumped_shreds;
440 // audio
441 BBQ * m_bbq;
443 // function table
444 // Chuck_VM_FTable * m_func_table;
445 // t_CKUINT m_num_func;
447 // message queue
448 CBufferSimple * m_msg_buffer;
449 CBufferSimple * m_reply_buffer;
450 CBufferSimple * m_event_buffer;
452 public:
453 // running
454 t_CKBOOL m_running;
456 // priority
457 static t_CKBOOL set_priority( t_CKINT priority, Chuck_VM * vm );
458 static t_CKINT our_priority;
464 //-----------------------------------------------------------------------------
465 // name: enum Chuck_Msg_Type
466 // desc: ...
467 //-----------------------------------------------------------------------------
468 enum Chuck_Msg_Type
470 MSG_ADD = 1,
471 MSG_REMOVE,
472 MSG_REMOVEALL,
473 MSG_REPLACE,
474 MSG_STATUS,
475 MSG_PAUSE,
476 MSG_KILL,
477 MSG_TIME,
478 MSG_RESET_ID,
479 MSG_DONE,
480 MSG_ABORT
486 // callback function prototype
487 typedef void (* ck_msg_func)( const Chuck_Msg * msg );
488 //-----------------------------------------------------------------------------
489 // name: struct Chuck_Msg
490 // desc: ...
491 //-----------------------------------------------------------------------------
492 struct Chuck_Msg
494 t_CKUINT type;
495 t_CKUINT param;
496 Chuck_VM_Code * code;
497 Chuck_VM_Shred * shred;
498 t_CKTIME when;
500 void * user;
501 ck_msg_func reply;
502 t_CKUINT replyA;
503 t_CKUINT replyB;
504 void * replyC;
506 std::vector<std::string> * args;
508 Chuck_Msg() { memset( this, 0, sizeof(*this) ); }
509 ~Chuck_Msg() { SAFE_DELETE( args ); }
511 void set( const std::vector<std::string> & vargs )
513 SAFE_DELETE(args);
514 args = new std::vector<std::string>;
515 (*args) = vargs;
522 #endif