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 //-----------------------------------------------------------------------------
27 // desc: chuck unit generator interface
29 // authors: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 //-----------------------------------------------------------------------------
33 #include "chuck_ugen.h"
40 //-----------------------------------------------------------------------------
43 //-----------------------------------------------------------------------------
44 Chuck_UGen::Chuck_UGen()
52 //-----------------------------------------------------------------------------
53 // name: ~Chuck_UGen()
55 //-----------------------------------------------------------------------------
56 Chuck_UGen::~Chuck_UGen()
64 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
68 void Chuck_UGen::init()
71 Chuck_VM_Object::init();
80 m_max_src
= 0xffffffff;
95 //-----------------------------------------------------------------------------
98 //-----------------------------------------------------------------------------
99 void Chuck_UGen::done()
102 shred
->remove( this );
104 assert( this->m_ref_count
== 0 );
113 //-----------------------------------------------------------------------------
114 // name: set_max_src()
116 //-----------------------------------------------------------------------------
117 t_CKBOOL
Chuck_UGen::set_max_src( t_CKUINT num
)
126 //-----------------------------------------------------------------------------
127 // name: get_num_src()
129 //-----------------------------------------------------------------------------
130 t_CKUINT
Chuck_UGen::get_num_src()
138 //-----------------------------------------------------------------------------
141 //-----------------------------------------------------------------------------
142 t_CKBOOL
Chuck_UGen::add( Chuck_UGen
* src
)
144 if( m_num_src
>= m_max_src
)
149 m_src_list
.push_back( src
);
159 //-----------------------------------------------------------------------------
162 //-----------------------------------------------------------------------------
163 void Chuck_UGen::add_by( Chuck_UGen
* dest
)
167 m_dest_list
.push_back( dest
);
173 //-----------------------------------------------------------------------------
176 //-----------------------------------------------------------------------------
177 t_CKBOOL
Chuck_UGen::remove( Chuck_UGen
* src
)
183 for( unsigned int i
= 0; i
< m_num_src
; i
++ )
184 if( m_src_list
[i
] == src
)
186 for( unsigned int j
= i
+1; j
< m_num_src
; j
++ )
187 m_src_list
[j
-1] = m_src_list
[j
];
189 m_src_list
[--m_num_src
] = NULL
;
190 m_src_list
.pop_back();
191 src
->remove_by( this );
201 //-----------------------------------------------------------------------------
204 //-----------------------------------------------------------------------------
205 void Chuck_UGen::remove_by( Chuck_UGen
* dest
)
208 for( unsigned int i
= 0; i
< m_num_dest
; i
++ )
209 if( m_dest_list
[i
] == dest
)
211 for( unsigned int j
= i
+1; j
< m_num_dest
; j
++ )
212 m_dest_list
[j
-1] = m_dest_list
[j
];
214 m_dest_list
[--m_num_dest
] = NULL
;
215 m_dest_list
.pop_back();
222 //-----------------------------------------------------------------------------
225 //-----------------------------------------------------------------------------
226 void Chuck_UGen::remove_all( )
228 assert( this->m_num_dest
== 0 );
231 for( unsigned int i
= 0; i
< m_num_src
; i
++ )
232 m_src_list
[i
]->release();
241 //-----------------------------------------------------------------------------
242 // name: disconnect()
244 //-----------------------------------------------------------------------------
245 t_CKBOOL
Chuck_UGen::disconnect( t_CKBOOL recursive
)
248 for( unsigned int i
= 0; i
< m_num_dest
; i
++ )
249 m_dest_list
[i
]->remove( this );
254 // disconnect src too?
264 //-----------------------------------------------------------------------------
267 //-----------------------------------------------------------------------------
268 t_CKBOOL
Chuck_UGen::system_tick( t_CKTIME now
)
276 m_sum
= m_num_src
&& m_src_list
[0]->system_tick( now
) ?
277 m_src_list
[0]->m_current
: 0.0f
;
280 for( t_CKUINT i
= 1; i
< m_num_src
; i
++ )
281 if( m_src_list
[i
]->system_tick( now
) )
284 m_sum
+= m_src_list
[i
]->m_current
;
289 case 2: m_sum
-= m_src_list
[i
]->m_current
; break;
290 case 3: m_sum
*= m_src_list
[i
]->m_current
; break;
291 case 4: m_sum
/= m_src_list
[i
]->m_current
; break;
292 default: m_sum
+= m_src_list
[i
]->m_current
; break;
297 if( m_op
> 0 ) // UGEN_OP_TICK
300 if( tick
) m_valid
= tick( now
, state
, m_sum
, &m_current
);
301 if( !m_valid
) m_current
= 0.0f
;
305 else if( m_op
< 0 ) // UGEN_OP_PASS
308 m_current
= m_sum
* m_gain
;