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
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 //-----------------------------------------------------------------------------
33 #ifndef __CHUCK_VM_H__
34 #define __CHUCK_VM_H__
37 #include "chuck_ugen.h"
40 #ifdef __CHUCK_STAT_TRACK__
41 #include "chuck_stats.h"
51 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
54 #define CVM_MEM_STACK_SIZE (0x1 << 16)
55 #define CVM_REG_STACK_SIZE (0x1 << 14)
62 struct Chuck_VM_FTable
;
72 //-----------------------------------------------------------------------------
73 // name: struct Chuck_VM_Stack
75 //-----------------------------------------------------------------------------
78 //-----------------------------------------------------------------------------
80 //-----------------------------------------------------------------------------
86 t_CKBOOL
initialize( t_CKUINT size
);
89 //-----------------------------------------------------------------------------
91 //-----------------------------------------------------------------------------
97 public: // linked list
98 Chuck_VM_Stack
* prev
;
99 Chuck_VM_Stack
* next
;
108 //-----------------------------------------------------------------------------
109 // name: struct Chuck_VM_Code
111 //-----------------------------------------------------------------------------
112 struct Chuck_VM_Code
: Chuck_Object
119 // array of Chuck_Instr *, should always end with Chuck_Instr_EOF
120 Chuck_Instr
** instr
;
126 // the depth of any function arguments
127 t_CKUINT stack_depth
;
128 // whether the function needs 'this' pointer or not
131 t_CKUINT native_func
;
133 t_CKUINT native_func_type
;
136 enum { NATIVE_UNKNOWN
, NATIVE_CTOR
, NATIVE_DTOR
, NATIVE_MFUN
, NATIVE_SFUN
};
142 //-----------------------------------------------------------------------------
143 // name: struct Chuck_VM_Shred
145 //-----------------------------------------------------------------------------
146 struct Chuck_VM_Shred
: Chuck_Object
148 //-----------------------------------------------------------------------------
150 //-----------------------------------------------------------------------------
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
);
159 t_CKBOOL
run( Chuck_VM
* vm
);
160 t_CKBOOL
add( Chuck_UGen
* ugen
);
161 t_CKBOOL
remove( Chuck_UGen
* ugen
);
163 //-----------------------------------------------------------------------------
165 //-----------------------------------------------------------------------------
166 public: // machine components
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
;
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
;
189 // state (no longer needed, see array_alloc)
190 // t_CKUINT * obj_array;
191 // t_CKUINT obj_array_size;
200 Chuck_Event
* event
; // event shred is waiting on
201 std::map
<Chuck_UGen
*, Chuck_UGen
*> m_ugen_map
;
206 std::vector
<std::string
> args
;
209 Chuck_VM_Shred
* prev
;
210 Chuck_VM_Shred
* next
;
213 CK_TRACK( Shred_Stat
* stat
);
219 //-----------------------------------------------------------------------------
220 // name: struct Chuck_VM_Shred_Status
222 //-----------------------------------------------------------------------------
223 struct Chuck_VM_Shred_Status
: Chuck_Object
232 Chuck_VM_Shred_Status( t_CKUINT _id
, const std::string
& n
, t_CKTIME _start
, t_CKBOOL e
)
244 //-----------------------------------------------------------------------------
245 // name: struct Chuck_VM_Status
247 //-----------------------------------------------------------------------------
248 struct Chuck_VM_Status
: Chuck_Object
264 // list of shred status
265 std::vector
<Chuck_VM_Shred_Status
*> list
;
271 //-----------------------------------------------------------------------------
272 // name: struct Chuck_VM_Shreduler
274 //-----------------------------------------------------------------------------
275 struct Chuck_VM_Shreduler
: Chuck_Object
277 //-----------------------------------------------------------------------------
279 //-----------------------------------------------------------------------------
281 Chuck_VM_Shreduler();
282 ~Chuck_VM_Shreduler();
285 t_CKBOOL
initialize();
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( );
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
);
300 void status( Chuck_VM_Status
* status
);
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 //-----------------------------------------------------------------------------
309 //-----------------------------------------------------------------------------
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
;
321 Chuck_VM_Shred
* m_current_shred
; // TODO: ref count?
326 Chuck_UGen
* m_bunghole
;
327 t_CKUINT m_num_dac_channels
;
328 t_CKUINT m_num_adc_channels
;
331 Chuck_VM_Status m_status
;
337 //-----------------------------------------------------------------------------
338 // name: struct Chuck_VM
340 //-----------------------------------------------------------------------------
341 struct Chuck_VM
: Chuck_Object
343 //-----------------------------------------------------------------------------
345 //-----------------------------------------------------------------------------
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( );
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;
368 t_CKUINT
srate() const;
369 void compensate_bbq();
371 public: // running the machine
373 t_CKBOOL
run( t_CKINT num_samps
);
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
385 void gc( t_CKUINT amount
);
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
; }
400 const char * last_error() const
401 { return m_last_error
.c_str(); }
403 //-----------------------------------------------------------------------------
405 //-----------------------------------------------------------------------------
410 Chuck_UGen
* m_bunghole
;
411 t_CKUINT m_num_adc_channels
;
412 t_CKUINT m_num_dac_channels
;
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
);
427 // t_CKBOOL m_running; -> moved to public
428 t_CKBOOL m_audio_started
;
429 std::string m_last_error
;
432 Chuck_VM_Shred
* m_shreds
;
433 t_CKUINT m_num_shreds
;
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
;
444 // Chuck_VM_FTable * m_func_table;
445 // t_CKUINT m_num_func;
448 CBufferSimple
* m_msg_buffer
;
449 CBufferSimple
* m_reply_buffer
;
450 CBufferSimple
* m_event_buffer
;
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
467 //-----------------------------------------------------------------------------
486 // callback function prototype
487 typedef void (* ck_msg_func
)( const Chuck_Msg
* msg
);
488 //-----------------------------------------------------------------------------
489 // name: struct Chuck_Msg
491 //-----------------------------------------------------------------------------
496 Chuck_VM_Code
* code
;
497 Chuck_VM_Shred
* shred
;
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
)
514 args
= new std::vector
<std::string
>;