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)
31 // Ananya Misra (amisra@cs.princeton.edu)
33 // Summer 2005 - updated
34 //-----------------------------------------------------------------------------
42 #if defined(__CK_SNDFILE_NATIVE__)
45 #include "util_sndfile.h"
49 #include "chuck_type.h"
50 #include "chuck_ugen.h"
52 #include "chuck_globals.h"
59 DLL_QUERY
lisa_query( Chuck_DL_Query
* query
);
65 static t_CKUINT stereo_offset_left
= 0;
66 static t_CKUINT stereo_offset_right
= 0;
67 static t_CKUINT stereo_offset_pan
= 0;
68 static t_CKUINT cnoise_offset_data
= 0;
69 static t_CKUINT impulse_offset_data
= 0;
70 static t_CKUINT step_offset_data
= 0;
71 static t_CKUINT delayp_offset_data
= 0;
72 static t_CKUINT sndbuf_offset_data
= 0;
73 static t_CKUINT dyno_offset_data
= 0;
74 // static t_CKUINT zerox_offset_data = 0;
76 Chuck_Type
* g_t_dac
= NULL
;
77 Chuck_Type
* g_t_adc
= NULL
;
80 //-----------------------------------------------------------------------------
83 //-----------------------------------------------------------------------------
84 DLL_QUERY
xxx_query( Chuck_DL_Query
* QUERY
)
86 g_srate
= QUERY
->srate
;
88 Chuck_Env
* env
= Chuck_Env::instance();
90 Chuck_DL_Func
* func
= NULL
;
93 type_engine_register_deprecate( env
, "dac", "DAC" );
94 type_engine_register_deprecate( env
, "adc", "ADC" );
95 type_engine_register_deprecate( env
, "pan2", "Pan2" );
96 type_engine_register_deprecate( env
, "mix2", "Mix2" );
97 type_engine_register_deprecate( env
, "gain", "Gain" );
98 type_engine_register_deprecate( env
, "noise", "Noise" );
99 type_engine_register_deprecate( env
, "cnoise", "CNoise" );
100 type_engine_register_deprecate( env
, "impulse", "Impulse" );
101 type_engine_register_deprecate( env
, "step", "Step" );
102 type_engine_register_deprecate( env
, "halfrect", "HalfRect" );
103 type_engine_register_deprecate( env
, "fullrect", "FullRect" );
104 type_engine_register_deprecate( env
, "zerox", "ZeroX" );
105 type_engine_register_deprecate( env
, "delayp", "DelayP" );
106 type_engine_register_deprecate( env
, "sndbuf", "SndBuf" );
108 //! \section audio output
110 //-------------------------------------------------------------------------
111 // init as base class: UGen_Multi
112 //-------------------------------------------------------------------------
113 if( !type_engine_import_ugen_begin( env
, "UGen_Multi", "UGen", env
->global(),
114 multi_ctor
, NULL
, NULL
, 0, 0 ) )
118 func
= make_new_mfun( "UGen", "chan", multi_cget_chan
);
119 func
->add_arg( "int", "which" );
120 if( !type_engine_import_mfun( env
, func
) ) goto error
;
123 /* func = make_new_mfun( "float", "pan", multi_ctrl_pan );
124 func->add_arg( "float", "val" );
125 if( !type_engine_import_mfun( env, func ) ) goto error;
126 func = make_new_mfun( "float", "pan", multi_cget_pan );
127 if( !type_engine_import_mfun( env, func ) ) goto error; */
130 //---------------------------------------------------------------------
131 // init as base class: UGen_Stereo
132 //---------------------------------------------------------------------
133 if( !type_engine_import_ugen_begin( env
, "UGen_Stereo", "UGen_Multi", env
->global(),
134 stereo_ctor
, NULL
, NULL
, NULL
, 2, 2 ) )
138 stereo_offset_left
= type_engine_import_mvar( env
, "UGen", "left", FALSE
);
139 if( stereo_offset_left
== CK_INVALID_OFFSET
) goto error
;
142 stereo_offset_right
= type_engine_import_mvar( env
, "UGen", "right", FALSE
);
143 if( stereo_offset_right
== CK_INVALID_OFFSET
) goto error
;
146 stereo_offset_pan
= type_engine_import_mvar( env
, "float", "@pan", FALSE
);
147 if( stereo_offset_pan
== CK_INVALID_OFFSET
) goto error
;
150 func
= make_new_mfun( "float", "pan", stereo_ctrl_pan
);
151 func
->add_arg( "float", "val" );
152 if( !type_engine_import_mfun( env
, func
) ) goto error
;
153 func
= make_new_mfun( "float", "pan", stereo_cget_pan
);
154 if( !type_engine_import_mfun( env
, func
) ) goto error
;
157 if( !type_engine_import_class_end( env
) )
161 //! digital/analog converter
162 //! abstraction for underlying audio output device
163 //---------------------------------------------------------------------
164 // init as base class: dac
165 //---------------------------------------------------------------------
166 if( !(g_t_dac
= type_engine_import_ugen_begin( env
, "DAC", "UGen_Stereo", env
->global(),
167 NULL
, NULL
, NULL
, NULL
, 2, 2 )) )
171 if( !type_engine_import_class_end( env
) )
175 //! analog/digital converter
176 //! abstraction for underlying audio input device
177 //---------------------------------------------------------------------
178 // init as base class: adc
179 //---------------------------------------------------------------------
180 if( !(g_t_adc
= type_engine_import_ugen_begin( env
, "ADC", "UGen_Stereo", env
->global(),
181 NULL
, NULL
, NULL
, NULL
, 0, 2 )) )
185 if( !type_engine_import_class_end( env
) )
188 //---------------------------------------------------------------------
189 // init as base class: pan2
190 //---------------------------------------------------------------------
191 if( !type_engine_import_ugen_begin( env
, "Pan2", "UGen_Stereo", env
->global(),
192 NULL
, NULL
, NULL
, NULL
, 2, 2 ) )
196 if( !type_engine_import_class_end( env
) )
199 //---------------------------------------------------------------------
200 // init as base class: mix2
201 //---------------------------------------------------------------------
202 if( !type_engine_import_ugen_begin( env
, "Mix2", "UGen_Stereo", env
->global(),
203 NULL
, NULL
, NULL
, NULL
, 2, 2 ) )
207 if( !type_engine_import_class_end( env
) )
211 //! sample rate sample sucker
212 //! ( like dac, ticks ugens, but no more )
213 //! see \example pwm.ck
214 //QUERY->ugen_add( QUERY, "blackhole", NULL );
216 //QUERY->ugen_func( QUERY, NULL, NULL, bunghole_tick, NULL );
219 //! sample rate sample sucker
220 //! ( like dac, ticks ugens, but no more )
221 //QUERY->ugen_add( QUERY, "bunghole", NULL );
223 //QUERY->ugen_func( QUERY, NULL, NULL, bunghole_tick, NULL );
227 //! (NOTE - all unit generators can themselves change their gain)
228 //! (this is a way to add N outputs together and scale them)
229 //! used in \example i-robot.ck
230 //---------------------------------------------------------------------
231 // init as base class: gain
232 //---------------------------------------------------------------------
233 if( !type_engine_import_ugen_begin( env
, "Gain", "UGen", env
->global(),
234 NULL
, NULL
, NULL
, NULL
) )
237 if( !type_engine_import_class_end( env
) )
240 noise n => gain g => dac;
243 while( true ) { 100::ms => now; }
246 //! \section wave forms
249 //! white noise generator
250 //! see \example noise.ck \example powerup.ck
251 //---------------------------------------------------------------------
252 // init as base class: noise
253 //---------------------------------------------------------------------
254 if( !type_engine_import_ugen_begin( env
, "Noise", "UGen", env
->global(),
255 NULL
, NULL
, noise_tick
, NULL
) )
259 if( !type_engine_import_class_end( env
) )
264 /*QUERY->ugen_add( QUERY, "cnoise", NULL );
265 QUERY->ugen_func( QUERY, cnoise_ctor, cnoise_dtor, cnoise_tick, NULL );
266 QUERY->ugen_ctrl( QUERY, cnoise_ctrl_mode, NULL, "string", "mode" );
267 QUERY->ugen_ctrl( QUERY, cnoise_ctrl_fprob, NULL, "float", "fprob" );*/
269 //---------------------------------------------------------------------
270 // init as base class: cnoise
271 //---------------------------------------------------------------------
272 if( !type_engine_import_ugen_begin( env
, "CNoise", "UGen", env
->global(),
273 cnoise_ctor
, cnoise_dtor
, cnoise_tick
, NULL
) )
276 // add member variable
277 cnoise_offset_data
= type_engine_import_mvar( env
, "int", "@cnoise_data", FALSE
);
278 if( cnoise_offset_data
== CK_INVALID_OFFSET
) goto error
;
281 func
= make_new_mfun( "string", "mode", cnoise_ctrl_mode
);
282 func
->add_arg( "string", "mode" );
283 if( !type_engine_import_mfun( env
, func
) ) goto error
;
285 //func = make_new_mfun( "string", "mode", cnoise_cget_mode );
286 //if( !type_engine_import_mfun( env, func ) ) goto error;
289 func
= make_new_mfun( "float", "fprob", cnoise_ctrl_fprob
);
290 func
->add_arg( "float", "fprob" );
291 if( !type_engine_import_mfun( env
, func
) ) goto error
;
293 //func = make_new_mfun( "float", "fprob", cnoise_cget_fprob );
294 //if( !type_engine_import_mfun( env, func ) ) goto error;
297 if( !type_engine_import_class_end( env
) )
302 //! pulse generator - can set the value of the current sample
303 //! default for each sample is 0 if not set
304 //QUERY->ugen_add( QUERY, "impulse", NULL );
306 //QUERY->ugen_func( QUERY, impulse_ctor, impulse_dtor, impulse_tick, NULL );
308 //QUERY->ugen_ctrl( QUERY, impulse_ctrl_value, impulse_cget_value, "float", "value" );
309 //QUERY->ugen_ctrl( QUERY, impulse_ctrl_value, impulse_cget_value, "float", "next" ); //! set value of next sample
318 //---------------------------------------------------------------------
319 // init as base class: impulse
320 //---------------------------------------------------------------------
321 if( !type_engine_import_ugen_begin( env
, "Impulse", "UGen", env
->global(),
322 impulse_ctor
, impulse_dtor
, impulse_tick
, NULL
) )
326 //func = make_new_mfun( "float", "value", impulse_ctrl_value );
327 //func->add_arg( "float", "value" );
328 //if( !type_engine_import_mfun( env, func ) ) goto error;
330 //func = make_new_mfun( "float", "value", impulse_cget_value );
331 //if( !type_engine_import_mfun( env, func ) ) goto error;
333 // add member variable
334 impulse_offset_data
= type_engine_import_mvar( env
, "int", "@impulse_data", FALSE
);
335 if( impulse_offset_data
== CK_INVALID_OFFSET
) goto error
;
338 func
= make_new_mfun( "float", "next", impulse_ctrl_next
);
339 func
->add_arg( "float", "next" );
340 if( !type_engine_import_mfun( env
, func
) ) goto error
;
342 func
= make_new_mfun( "float", "next", impulse_cget_next
);
343 if( !type_engine_import_mfun( env
, func
) ) goto error
;
346 if( !type_engine_import_class_end( env
) )
350 //! step generator - like impulse, but once a value is set,
351 //! it is held for all following samples, until value is set again
352 //! see \example step.ck
353 //QUERY->ugen_add( QUERY, "step", NULL );
355 //QUERY->ugen_func( QUERY, step_ctor, step_dtor, step_tick, NULL );
357 //QUERY->ugen_ctrl( QUERY, step_ctrl_value, step_cget_value, "float", "value" );
358 //QUERY->ugen_ctrl( QUERY, step_ctrl_value, step_cget_value, "float", "next" ); //! set the step value
363 // square wave using step
365 -amp => amp => s.next;
369 //---------------------------------------------------------------------
370 // init as base class: step
371 //---------------------------------------------------------------------
372 if( !type_engine_import_ugen_begin( env
, "Step", "UGen", env
->global(),
373 step_ctor
, step_dtor
, step_tick
, NULL
) )
377 //func = make_new_mfun( "float", "value", step_ctrl_value );
378 //func->add_arg( "float", "value" );
379 //if( !type_engine_import_mfun( env, func ) ) goto error;
381 //func = make_new_mfun( "float", "value", step_cget_value );
382 //if( !type_engine_import_mfun( env, func ) ) goto error;
384 // add member variable
385 step_offset_data
= type_engine_import_mvar( env
, "int", "@step_data", FALSE
);
386 if( step_offset_data
== CK_INVALID_OFFSET
) goto error
;
389 func
= make_new_mfun( "float", "next", step_ctrl_next
);
390 func
->add_arg( "float", "next" );
391 if( !type_engine_import_mfun( env
, func
) ) goto error
;
393 func
= make_new_mfun( "float", "next", step_cget_next
);
394 if( !type_engine_import_mfun( env
, func
) ) goto error
;
397 if( !type_engine_import_class_end( env
) )
401 //! half wave rectifier
402 //! for half-wave rectification.
403 //QUERY->ugen_add( QUERY, "halfrect", NULL );
405 //QUERY->ugen_func( QUERY, NULL, NULL, halfrect_tick, NULL );
406 //---------------------------------------------------------------------
407 // init as base class: halfrect
408 //---------------------------------------------------------------------
409 if( !type_engine_import_ugen_begin( env
, "HalfRect", "UGen", env
->global(),
410 NULL
, NULL
, halfrect_tick
, NULL
) )
414 if( !type_engine_import_class_end( env
) )
419 //! full wave rectifier
420 //QUERY->ugen_add( QUERY, "fullrect", NULL );
422 //QUERY->ugen_func( QUERY, NULL, NULL, fullrect_tick, NULL );
423 //---------------------------------------------------------------------
424 // init as base class: fullrect
425 //---------------------------------------------------------------------
426 if( !type_engine_import_ugen_begin( env
, "FullRect", "UGen", env
->global(),
427 NULL
, NULL
, fullrect_tick
, NULL
) )
431 if( !type_engine_import_class_end( env
) )
436 //! zero crossing detector
437 //! emits a single pulse at the the zero crossing in the direction of the zero crossing.
438 //! (see \example zerox.ck)
439 //QUERY->ugen_add( QUERY, "zerox", NULL );
441 //QUERY->ugen_func( QUERY, zerox_ctor, zerox_dtor, zerox_tick, NULL );
442 //---------------------------------------------------------------------
443 // init as base class: zerox
444 //---------------------------------------------------------------------
445 /* if( !type_engine_import_ugen_begin( env, "ZeroX", "UGen", env->global(),
446 zerox_ctor, zerox_dtor, zerox_tick, NULL ) )
449 // add member variable
450 zerox_offset_data = type_engine_import_mvar( env, "int", "@zerox_data", FALSE );
451 if( zerox_offset_data == CK_INVALID_OFFSET ) goto error;
454 if( !type_engine_import_class_end( env ) )
458 //! \section delay lines
460 //! delay with varying write position ( instead of read position )
461 //! change to delay length will not affect the delay of samples already in
463 //! see \example delayp.ck
465 //QUERY->ugen_add( QUERY, "delayp" , NULL);
466 //QUERY->ugen_func ( QUERY, delayp_ctor, delayp_dtor, delayp_tick, delayp_pmsg);
467 //QUERY->ugen_ctrl( QUERY, delayp_ctrl_delay, delayp_cget_delay , "dur", "delay" ); //! delay before subsequent values emerge
468 //QUERY->ugen_ctrl( QUERY, delayp_ctrl_window, delayp_cget_window , "dur", "window" ); //! time for 'write head' to move
469 //QUERY->ugen_ctrl( QUERY, delayp_ctrl_max, delayp_cget_max , "dur", "max" ); //! max delay possible. trashes buffer, so do it first!
471 //---------------------------------------------------------------------
472 // init as base class: delayp
473 //---------------------------------------------------------------------
474 if( !type_engine_import_ugen_begin( env
, "DelayP", "UGen", env
->global(),
475 delayp_ctor
, delayp_dtor
,
476 delayp_tick
, delayp_pmsg
) )
479 // add member variable
480 delayp_offset_data
= type_engine_import_mvar( env
, "int", "@delayp_data", FALSE
);
481 if( delayp_offset_data
== CK_INVALID_OFFSET
) goto error
;
484 func
= make_new_mfun( "dur", "delay", delayp_ctrl_delay
);
485 func
->add_arg( "dur", "delay" );
486 if( !type_engine_import_mfun( env
, func
) ) goto error
;
488 func
= make_new_mfun( "dur", "delay", delayp_cget_delay
);
489 if( !type_engine_import_mfun( env
, func
) ) goto error
;
492 func
= make_new_mfun( "dur", "window", delayp_ctrl_window
);
493 func
->add_arg( "dur", "window" );
494 if( !type_engine_import_mfun( env
, func
) ) goto error
;
496 func
= make_new_mfun( "dur", "window", delayp_cget_window
);
497 if( !type_engine_import_mfun( env
, func
) ) goto error
;
500 func
= make_new_mfun( "dur", "max", delayp_ctrl_max
);
501 func
->add_arg( "dur", "max" );
502 if( !type_engine_import_mfun( env
, func
) ) goto error
;
504 func
= make_new_mfun( "dur", "max", delayp_cget_max
);
505 if( !type_engine_import_mfun( env
, func
) ) goto error
;
508 if( !type_engine_import_class_end( env
) )
511 //! \section sound files
513 #ifndef __DISABLE_SNDBUF__
516 //! sound buffer ( now interpolating )
517 //! reads from a variety of file formats
518 //! see \example sndbuf.ck
519 //QUERY->ugen_add( QUERY, "sndbuf", NULL );
521 //QUERY->ugen_func( QUERY, sndbuf_ctor, sndbuf_dtor, sndbuf_tick, NULL );
523 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_read, NULL, "string", "read" ); //! loads file for reading
524 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_write, NULL, "string", "write" ); //! loads a file for writing ( or not )
525 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_pos, sndbuf_cget_pos, "int", "pos" ); //! set position ( 0 < p < .samples )
526 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_loop, sndbuf_cget_loop, "int", "loop" ); //! toggle looping
527 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_interp, sndbuf_cget_interp, "int", "interp" ); //! set interpolation ( 0=drop, 1=linear, 2=sinc )
528 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_rate, sndbuf_cget_rate, "float", "rate" ); //! playback rate ( relative to file's natural speed )
529 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_rate, sndbuf_cget_rate, "float", "play" ); //! play (same as rate)
530 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_freq, sndbuf_cget_freq, "float", "freq" ); //! playback rate ( file loops / second )
531 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_phase, sndbuf_cget_phase, "float", "phase" ); //! set phase position ( 0-1 )
532 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_channel, sndbuf_cget_channel, "int", "channel" ); //! select channel ( 0 < p < .channels )
533 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_phase_offset, sndbuf_cget_phase, "float", "phase_offset" ); //! set a phase offset
534 //QUERY->ugen_ctrl( QUERY, NULL, sndbuf_cget_samples, "int", "samples" ); //! fetch number of samples
535 //QUERY->ugen_ctrl( QUERY, NULL, sndbuf_cget_length, "dur", "length" ); //! fetch length
536 //QUERY->ugen_ctrl( QUERY, NULL, sndbuf_cget_channels, "int", "channels" ); //! fetch number of channels
538 //---------------------------------------------------------------------
539 // init as base class: sndbuf
540 //---------------------------------------------------------------------
541 if( !type_engine_import_ugen_begin( env
, "SndBuf", "UGen", env
->global(),
542 sndbuf_ctor
, sndbuf_dtor
,
543 sndbuf_tick
, NULL
) )
546 // add member variable
547 sndbuf_offset_data
= type_engine_import_mvar( env
, "int", "@sndbuf_data", FALSE
);
548 if( sndbuf_offset_data
== CK_INVALID_OFFSET
) goto error
;
551 func
= make_new_mfun( "string", "read", sndbuf_ctrl_read
);
552 func
->add_arg( "string", "read" );
553 if( !type_engine_import_mfun( env
, func
) ) goto error
;
554 // add cget: read // area
555 //func = make_new_mfun( "string", "read", sndbuf_cget_read );
556 //if( !type_engine_import_mfun( env, func ) ) goto error;
559 func
= make_new_mfun( "string", "write", sndbuf_ctrl_write
);
560 func
->add_arg( "string", "read" );
561 if( !type_engine_import_mfun( env
, func
) ) goto error
;
563 //func = make_new_mfun( "string", "write", sndbuf_cget_write );
564 //if( !type_engine_import_mfun( env, func ) ) goto error;
567 func
= make_new_mfun( "int", "pos", sndbuf_ctrl_pos
);
568 func
->add_arg( "int", "pos" );
569 if( !type_engine_import_mfun( env
, func
) ) goto error
;
571 func
= make_new_mfun( "int", "pos", sndbuf_cget_pos
);
572 if( !type_engine_import_mfun( env
, func
) ) goto error
;
575 func
= make_new_mfun( "int", "loop", sndbuf_ctrl_loop
);
576 func
->add_arg( "int", "loop" );
577 if( !type_engine_import_mfun( env
, func
) ) goto error
;
579 func
= make_new_mfun( "int", "loop", sndbuf_cget_loop
);
580 if( !type_engine_import_mfun( env
, func
) ) goto error
;
583 func
= make_new_mfun( "int", "interp", sndbuf_ctrl_interp
);
584 func
->add_arg( "int", "interp" );
585 if( !type_engine_import_mfun( env
, func
) ) goto error
;
587 func
= make_new_mfun( "int", "interp", sndbuf_cget_interp
);
588 if( !type_engine_import_mfun( env
, func
) ) goto error
;
591 func
= make_new_mfun( "float", "rate", sndbuf_ctrl_rate
);
592 func
->add_arg( "float", "rate" );
593 if( !type_engine_import_mfun( env
, func
) ) goto error
;
595 func
= make_new_mfun( "float", "rate", sndbuf_cget_rate
);
596 if( !type_engine_import_mfun( env
, func
) ) goto error
;
599 func
= make_new_mfun( "float", "play", sndbuf_ctrl_rate
);
600 func
->add_arg( "float", "play" );
601 if( !type_engine_import_mfun( env
, func
) ) goto error
;
602 // add cget: play // good
603 func
= make_new_mfun( "float", "play", sndbuf_cget_rate
);
604 if( !type_engine_import_mfun( env
, func
) ) goto error
;
607 func
= make_new_mfun( "float", "freq", sndbuf_ctrl_freq
);
608 func
->add_arg( "float", "freq" );
609 if( !type_engine_import_mfun( env
, func
) ) goto error
;
611 func
= make_new_mfun( "float", "freq", sndbuf_cget_freq
);
612 if( !type_engine_import_mfun( env
, func
) ) goto error
;
615 func
= make_new_mfun( "float", "phase", sndbuf_ctrl_phase
);
616 func
->add_arg( "float", "phase" );
617 if( !type_engine_import_mfun( env
, func
) ) goto error
;
619 func
= make_new_mfun( "float", "phase", sndbuf_cget_phase
);
620 if( !type_engine_import_mfun( env
, func
) ) goto error
;
623 func
= make_new_mfun( "int", "channel", sndbuf_ctrl_channel
);
624 func
->add_arg( "int", "channel" );
625 if( !type_engine_import_mfun( env
, func
) ) goto error
;
627 func
= make_new_mfun( "int", "channel", sndbuf_cget_channel
);
628 if( !type_engine_import_mfun( env
, func
) ) goto error
;
630 // add ctrl: phase_offset
631 func
= make_new_mfun( "float", "phaseOffset", sndbuf_ctrl_phase_offset
);
632 func
->add_arg( "float", "value" );
633 if( !type_engine_import_mfun( env
, func
) ) goto error
;
634 // add cget: phase_offset
635 // func = make_new_mfun( "float", "phaseOffset", sndbuf_cget_phase_offset );
636 // if( !type_engine_import_mfun( env, func ) ) goto error;
639 func
= make_new_mfun( "int", "chunks", sndbuf_ctrl_chunks
);
640 func
->add_arg( "int", "frames" );
641 if( !type_engine_import_mfun( env
, func
) ) goto error
;
643 func
= make_new_mfun( "int", "chunks", sndbuf_cget_chunks
);
644 if( !type_engine_import_mfun( env
, func
) ) goto error
;
647 func
= make_new_mfun( "int", "samples", sndbuf_cget_samples
);
648 if( !type_engine_import_mfun( env
, func
) ) goto error
;
651 func
= make_new_mfun( "dur", "length", sndbuf_cget_length
);
652 if( !type_engine_import_mfun( env
, func
) ) goto error
;
654 // add cget: channels
655 func
= make_new_mfun( "int", "channels", sndbuf_cget_channels
);
656 if( !type_engine_import_mfun( env
, func
) ) goto error
;
659 func
= make_new_mfun( "float", "valueAt", sndbuf_cget_valueAt
);
660 func
->add_arg( "int", "pos" );
661 if( !type_engine_import_mfun( env
, func
) ) goto error
;
664 if( !type_engine_import_class_end( env
) )
667 #endif // __DISABLE_SNDBUF__
670 //---------------------------------------------------------------------
671 // init as base class: Dyno
672 //---------------------------------------------------------------------
673 if( !type_engine_import_ugen_begin( env
, "Dyno", "UGen", env
->global(),
674 dyno_ctor
, dyno_dtor
, dyno_tick
, NULL
) )
677 // add member variable
678 dyno_offset_data
= type_engine_import_mvar( env
, "int", "@dyno_data", FALSE
);
679 if( dyno_offset_data
== CK_INVALID_OFFSET
) goto error
;
682 func
= make_new_mfun( "void", "limit", dyno_ctrl_limit
);
683 //func->add_arg( "string", "mode" );
684 if( !type_engine_import_mfun( env
, func
) ) goto error
;
686 // add ctrl: compress
687 func
= make_new_mfun( "void", "compress", dyno_ctrl_compress
);
688 //func->add_arg( "string", "mode" );
689 if( !type_engine_import_mfun( env
, func
) ) goto error
;
692 func
= make_new_mfun( "void", "gate", dyno_ctrl_gate
);
693 //func->add_arg( "string", "mode" );
694 if( !type_engine_import_mfun( env
, func
) ) goto error
;
697 func
= make_new_mfun( "void", "expand", dyno_ctrl_expand
);
698 //func->add_arg( "string", "mode" );
699 if( !type_engine_import_mfun( env
, func
) ) goto error
;
702 func
= make_new_mfun( "void", "duck", dyno_ctrl_duck
);
703 //func->add_arg( "string", "mode" );
704 if( !type_engine_import_mfun( env
, func
) ) goto error
;
707 func
= make_new_mfun( "float", "thresh", dyno_ctrl_thresh
);
708 func
->add_arg( "float", "thresh" );
709 if( !type_engine_import_mfun( env
, func
) ) goto error
;
712 func
= make_new_mfun( "float", "thresh", dyno_cget_thresh
);
713 if( !type_engine_import_mfun( env
, func
) ) goto error
;
715 //add ctrl: attackTime
716 func
= make_new_mfun( "dur", "attackTime", dyno_ctrl_attackTime
);
717 func
->add_arg( "dur", "aTime" );
718 if( !type_engine_import_mfun( env
, func
) ) goto error
;
720 //add cget: attackTime
721 func
= make_new_mfun( "dur", "attackTime", dyno_ctrl_attackTime
);
722 if( !type_engine_import_mfun( env
, func
) ) goto error
;
724 //add ctrl: releaseTime
725 func
= make_new_mfun( "dur", "releaseTime", dyno_ctrl_releaseTime
);
726 func
->add_arg( "dur", "rTime" );
727 if( !type_engine_import_mfun( env
, func
) ) goto error
;
729 //add ctrl: releaseTime
730 func
= make_new_mfun( "dur", "releaseTime", dyno_ctrl_releaseTime
);
731 if( !type_engine_import_mfun( env
, func
) ) goto error
;
734 func
= make_new_mfun( "float", "ratio", dyno_ctrl_ratio
);
735 func
->add_arg( "float", "ratio" );
736 if( !type_engine_import_mfun( env
, func
) ) goto error
;
739 func
= make_new_mfun( "float", "ratio", dyno_cget_ratio
);
740 if( !type_engine_import_mfun( env
, func
) ) goto error
;
742 //add ctrl: slopeBelow
743 func
= make_new_mfun( "float", "slopeBelow", dyno_ctrl_slopeBelow
);
744 func
->add_arg( "float", "slopeBelow" );
745 if( !type_engine_import_mfun( env
, func
) ) goto error
;
747 //add cget: slopeBelow
748 func
= make_new_mfun( "float", "slopeBelow", dyno_cget_slopeBelow
);
749 if( !type_engine_import_mfun( env
, func
) ) goto error
;
751 //add ctrl: slopeAbove
752 func
= make_new_mfun( "float", "slopeAbove", dyno_ctrl_slopeAbove
);
753 func
->add_arg( "float", "slopeAbove" );
754 if( !type_engine_import_mfun( env
, func
) ) goto error
;
756 //add cget: slopeAbove
757 func
= make_new_mfun( "float", "slopeAbove", dyno_cget_slopeAbove
);
758 if( !type_engine_import_mfun( env
, func
) ) goto error
;
760 //add ctrl: sideInput
761 func
= make_new_mfun( "float", "sideInput", dyno_ctrl_sideInput
);
762 func
->add_arg( "float", "sideInput" );
763 if( !type_engine_import_mfun( env
, func
) ) goto error
;
765 //add cget: sideInput
766 func
= make_new_mfun( "float", "sideInput", dyno_cget_sideInput
);
767 if( !type_engine_import_mfun( env
, func
) ) goto error
;
769 //add ctrl: externalSideInput
770 func
= make_new_mfun( "int", "externalSideInput", dyno_ctrl_externalSideInput
);
771 func
->add_arg( "int", "externalSideInput" );
772 if( !type_engine_import_mfun( env
, func
) ) goto error
;
774 //add cget: externalSideInput
775 func
= make_new_mfun( "int", "externalSideInput", dyno_cget_externalSideInput
);
776 if( !type_engine_import_mfun( env
, func
) ) goto error
;
779 if( !type_engine_import_class_end( env
) )
783 if( !lisa_query( QUERY
) )
790 // end the class import
791 type_engine_import_class_end( env
);
799 // LiSa (live sampling data offset)
800 static t_CKUINT LiSaBasic_offset_data
= 0;
801 static t_CKUINT LiSaMulti_offset_data
= 0;
803 //-----------------------------------------------------------------------------
804 // name: lisa_query()
806 //-----------------------------------------------------------------------------
807 DLL_QUERY
lisa_query( Chuck_DL_Query
* QUERY
)
809 Chuck_Env
* env
= Chuck_Env::instance();
810 Chuck_DL_Func
* func
= NULL
;
812 //---------------------------------------------------------------------
813 // init class: LiSa; overloaded class for both LiSaBasic and LiSaMulti
814 // - probably don't need the others anymore....
815 // author: Dan Trueman (dan /at/ music.princeton.edu)
816 //---------------------------------------------------------------------
817 if( !type_engine_import_ugen_begin( env
, "LiSa", "UGen", env
->global(),
818 LiSaMulti_ctor
, LiSaMulti_dtor
,
819 LiSaMulti_tick
, LiSaMulti_pmsg
) )
822 // set/get buffer size
823 func
= make_new_mfun( "dur", "duration", LiSaMulti_size
);
824 func
->add_arg( "dur", "val" );
825 if( !type_engine_import_mfun( env
, func
) ) goto error
;
826 func
= make_new_mfun( "dur", "duration", LiSaMulti_cget_size
);
827 if( !type_engine_import_mfun( env
, func
) ) goto error
;
829 // start/stop recording
830 func
= make_new_mfun( "int", "record", LiSaMulti_start_record
);
831 func
->add_arg( "int", "toggle" );
832 if( !type_engine_import_mfun( env
, func
) ) goto error
;
834 // start/stop playing
835 func
= make_new_mfun( "int", "play", LiSaMulti_start_play
);
836 func
->add_arg( "int", "voice" );
837 func
->add_arg( "int", "toggle" );
838 if( !type_engine_import_mfun( env
, func
) ) goto error
;
839 func
= make_new_mfun( "int", "play", LiSaMulti_start_play0
);
840 func
->add_arg( "int", "toggle" );
841 if( !type_engine_import_mfun( env
, func
) ) goto error
;
843 // set/get playback rate
844 func
= make_new_mfun( "float", "rate", LiSaMulti_ctrl_rate
);
845 func
->add_arg( "int", "voice" );
846 func
->add_arg( "float", "val" );
847 if( !type_engine_import_mfun( env
, func
) ) goto error
;
848 func
= make_new_mfun( "float", "rate", LiSaMulti_cget_rate
);
849 func
->add_arg( "int", "voice" );
850 if( !type_engine_import_mfun( env
, func
) ) goto error
;
851 func
= make_new_mfun( "float", "rate", LiSaMulti_ctrl_rate0
);
852 func
->add_arg( "float", "val" );
853 if( !type_engine_import_mfun( env
, func
) ) goto error
;
854 func
= make_new_mfun( "float", "rate", LiSaMulti_cget_rate0
);
855 if( !type_engine_import_mfun( env
, func
) ) goto error
;
858 func
= make_new_mfun( "dur", "playPos", LiSaMulti_ctrl_pindex
);
859 func
->add_arg( "int", "voice" );
860 func
->add_arg( "dur", "val" );
861 if( !type_engine_import_mfun( env
, func
) ) goto error
;
862 func
= make_new_mfun( "dur", "playPos", LiSaMulti_cget_pindex
);
863 func
->add_arg( "int", "voice" );
864 if( !type_engine_import_mfun( env
, func
) ) goto error
;
865 func
= make_new_mfun( "dur", "playPos", LiSaMulti_ctrl_pindex0
);
866 func
->add_arg( "dur", "val" );
867 if( !type_engine_import_mfun( env
, func
) ) goto error
;
868 func
= make_new_mfun( "dur", "playPos", LiSaMulti_cget_pindex0
);
869 if( !type_engine_import_mfun( env
, func
) ) goto error
;
872 func
= make_new_mfun( "dur", "recPos", LiSaMulti_ctrl_rindex
);
873 func
->add_arg( "dur", "val" );
874 if( !type_engine_import_mfun( env
, func
) ) goto error
;
875 func
= make_new_mfun( "dur", "recPos", LiSaMulti_cget_rindex
);
876 if( !type_engine_import_mfun( env
, func
) ) goto error
;
878 // loopstart position
879 func
= make_new_mfun( "dur", "loopStart", LiSaMulti_ctrl_lstart
);
880 func
->add_arg( "int", "voice" );
881 func
->add_arg( "dur", "val" );
882 if( !type_engine_import_mfun( env
, func
) ) goto error
;
883 func
= make_new_mfun( "dur", "loopStart", LiSaMulti_cget_lstart
);
884 func
->add_arg( "int", "voice" );
885 if( !type_engine_import_mfun( env
, func
) ) goto error
;
886 func
= make_new_mfun( "dur", "loopStart", LiSaMulti_ctrl_lstart0
);
887 func
->add_arg( "dur", "val" );
888 if( !type_engine_import_mfun( env
, func
) ) goto error
;
889 func
= make_new_mfun( "dur", "loopStart", LiSaMulti_cget_lstart0
);
890 if( !type_engine_import_mfun( env
, func
) ) goto error
;
893 func
= make_new_mfun( "dur", "loopEnd", LiSaMulti_ctrl_lend
);
894 func
->add_arg( "int", "voice" );
895 func
->add_arg( "dur", "val" );
896 if( !type_engine_import_mfun( env
, func
) ) goto error
;
897 func
= make_new_mfun( "dur", "loopEnd", LiSaMulti_cget_lend
);
898 func
->add_arg( "int", "voice" );
899 if( !type_engine_import_mfun( env
, func
) ) goto error
;
900 func
= make_new_mfun( "dur", "loopEnd", LiSaMulti_ctrl_lend0
);
901 func
->add_arg( "dur", "val" );
902 if( !type_engine_import_mfun( env
, func
) ) goto error
;
903 func
= make_new_mfun( "dur", "loopEnd", LiSaMulti_cget_lend0
);
904 if( !type_engine_import_mfun( env
, func
) ) goto error
;
907 func
= make_new_mfun( "int", "loop", LiSaMulti_ctrl_loop
);
908 func
->add_arg( "int", "voice" );
909 func
->add_arg( "int", "val" );
910 if( !type_engine_import_mfun( env
, func
) ) goto error
;
911 func
= make_new_mfun( "int", "loop", LiSaMulti_cget_loop
);
912 func
->add_arg( "int", "voice" );
913 if( !type_engine_import_mfun( env
, func
) ) goto error
;
914 func
= make_new_mfun( "int", "loop", LiSaMulti_ctrl_loop0
);
915 func
->add_arg( "int", "val" );
916 if( !type_engine_import_mfun( env
, func
) ) goto error
;
917 func
= make_new_mfun( "int", "loop", LiSaMulti_cget_loop0
);
918 if( !type_engine_import_mfun( env
, func
) ) goto error
;
920 // bidirectional looping
921 func
= make_new_mfun( "int", "bi", LiSaMulti_ctrl_bi
);
922 func
->add_arg( "int", "voice" );
923 func
->add_arg( "int", "val" );
924 if( !type_engine_import_mfun( env
, func
) ) goto error
;
925 func
= make_new_mfun( "int", "bi", LiSaMulti_cget_bi
);
926 func
->add_arg( "int", "voice" );
927 if( !type_engine_import_mfun( env
, func
) ) goto error
;
928 func
= make_new_mfun( "int", "bi", LiSaMulti_ctrl_bi0
);
929 func
->add_arg( "int", "val" );
930 if( !type_engine_import_mfun( env
, func
) ) goto error
;
931 func
= make_new_mfun( "int", "bi", LiSaMulti_cget_bi0
);
932 if( !type_engine_import_mfun( env
, func
) ) goto error
;
934 // loopend_rec position
935 func
= make_new_mfun( "dur", "loopEndRec", LiSaMulti_ctrl_loop_end_rec
);
936 func
->add_arg( "dur", "val" );
937 if( !type_engine_import_mfun( env
, func
) ) goto error
;
938 func
= make_new_mfun( "dur", "loopEndRec", LiSaMulti_cget_loop_end_rec
);
939 if( !type_engine_import_mfun( env
, func
) ) goto error
;
941 // loop_rec toggle set; for turning on/off loop recording
942 func
= make_new_mfun( "int", "loopRec", LiSaMulti_ctrl_loop_rec
);
943 func
->add_arg( "int", "val" );
944 if( !type_engine_import_mfun( env
, func
) ) goto error
;
945 func
= make_new_mfun( "int", "loopRec", LiSaMulti_cget_loop_rec
);
946 if( !type_engine_import_mfun( env
, func
) ) goto error
;
948 // look at or put sample directly in record buffer, do not pass go
949 func
= make_new_mfun( "float", "valueAt", LiSaMulti_ctrl_sample
);
950 func
->add_arg( "float", "val" );
951 func
->add_arg( "dur", "index" );
952 if( !type_engine_import_mfun( env
, func
) ) goto error
;
953 func
= make_new_mfun( "float", "valueAt", LiSaMulti_cget_sample
);
954 func
->add_arg( "dur", "index" );
955 if( !type_engine_import_mfun( env
, func
) ) goto error
;
958 func
= make_new_mfun( "float", "voiceGain", LiSaMulti_ctrl_voicegain
);
959 func
->add_arg( "int", "voice" );
960 func
->add_arg( "float", "val" );
961 if( !type_engine_import_mfun( env
, func
) ) goto error
;
962 func
= make_new_mfun( "float", "voiceGain", LiSaMulti_cget_voicegain
);
963 func
->add_arg( "int", "voice" );
965 // set record feedback coefficient
966 func
= make_new_mfun( "float", "feedback", LiSaMulti_ctrl_coeff
);
967 func
->add_arg( "float", "val" );
968 if( !type_engine_import_mfun( env
, func
) ) goto error
;
969 func
= make_new_mfun( "float", "feedback", LiSaMulti_cget_coeff
);
970 if( !type_engine_import_mfun( env
, func
) ) goto error
;
973 func
= make_new_mfun( "void", "clear", LiSaMulti_ctrl_clear
);
974 if( !type_engine_import_mfun( env
, func
) ) goto error
;
977 func
= make_new_mfun( "int", "getVoice", LiSaMulti_cget_voice
);
978 if( !type_engine_import_mfun( env
, func
) ) goto error
;
981 func
= make_new_mfun( "int", "maxVoices", LiSaMulti_ctrl_maxvoices
);
982 func
->add_arg( "int", "val" );
983 if( !type_engine_import_mfun( env
, func
) ) goto error
;
984 func
= make_new_mfun( "int", "maxVoices", LiSaMulti_cget_maxvoices
);
985 if( !type_engine_import_mfun( env
, func
) ) goto error
;
988 func
= make_new_mfun( "void", "rampUp", LiSaMulti_ctrl_rampup
);
989 func
->add_arg( "int", "voice" );
990 func
->add_arg( "dur", "val" );
991 if( !type_engine_import_mfun( env
, func
) ) goto error
;
993 func
= make_new_mfun( "void", "rampDown", LiSaMulti_ctrl_rampdown
);
994 func
->add_arg( "int", "voice" );
995 func
->add_arg( "dur", "val" );
996 if( !type_engine_import_mfun( env
, func
) ) goto error
;
998 func
= make_new_mfun( "dur", "recRamp", LiSaMulti_ctrl_rec_ramplen
);
999 func
->add_arg( "dur", "val" );
1000 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1002 func
= make_new_mfun( "void", "rampUp", LiSaMulti_ctrl_rampup0
);
1003 func
->add_arg( "dur", "val" );
1004 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1006 func
= make_new_mfun( "void", "rampDown", LiSaMulti_ctrl_rampdown0
);
1007 func
->add_arg( "dur", "val" );
1008 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1011 func
= make_new_mfun( "dur", "value", LiSaMulti_cget_value
);
1012 func
->add_arg( "int", "voice" );
1013 func
->add_arg( "dur", "val" );
1014 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1015 func
= make_new_mfun( "dur", "value", LiSaMulti_cget_value0
);
1016 func
->add_arg( "dur", "val" );
1017 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1020 func
= make_new_mfun( "int", "track", LiSaMulti_ctrl_track
);
1021 func
->add_arg( "int", "val" );
1022 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1023 func
= make_new_mfun( "int", "track", LiSaMulti_cget_track
);
1024 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1027 func
= make_new_mfun( "int", "sync", LiSaMulti_ctrl_track
);
1028 func
->add_arg( "int", "val" );
1029 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1030 func
= make_new_mfun( "int", "sync", LiSaMulti_cget_track
);
1031 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1034 func
= make_new_mfun( "int", "sync", LiSaMulti_ctrl_track
);
1035 func
->add_arg( "int", "val" );
1036 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1037 func
= make_new_mfun( "int", "sync", LiSaMulti_cget_track
);
1038 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1040 // end the class import
1041 type_engine_import_class_end( env
);
1047 // end the class import
1048 type_engine_import_class_end( env
);
1056 //-----------------------------------------------------------------------------
1057 // name: multi_ctor()
1059 //-----------------------------------------------------------------------------
1060 CK_DLL_CTOR( multi_ctor
)
1068 //-----------------------------------------------------------------------------
1069 // name: multi_cget_chan()
1071 //-----------------------------------------------------------------------------
1072 CK_DLL_CGET( multi_cget_chan
)
1075 Chuck_UGen
* ugen
= (Chuck_UGen
*)SELF
;
1077 t_CKINT index
= GET_NEXT_INT( ARGS
);
1079 RETURN
->v_object
= index
>= 0 && index
< ugen
->m_multi_chan_size
?
1080 ugen
->m_multi_chan
[index
] : NULL
;
1086 //-----------------------------------------------------------------------------
1087 // name: stereo_ctor()
1089 //-----------------------------------------------------------------------------
1090 CK_DLL_CTOR( stereo_ctor
)
1093 Chuck_UGen
* ugen
= (Chuck_UGen
*)SELF
;
1096 if( ugen
->m_multi_chan_size
)
1099 OBJ_MEMBER_UINT(SELF
, stereo_offset_left
) = (t_CKUINT
)(ugen
->m_multi_chan
[0]);
1101 OBJ_MEMBER_UINT(SELF
, stereo_offset_right
) = (t_CKUINT
)(ugen
->m_multi_chan
[1]);
1105 // set left and right to self
1106 OBJ_MEMBER_UINT(SELF
, stereo_offset_left
) = (t_CKUINT
)ugen
;
1107 OBJ_MEMBER_UINT(SELF
, stereo_offset_right
) = (t_CKUINT
)ugen
;
1114 //-----------------------------------------------------------------------------
1115 // name: stereo_ctrl_pan()
1117 //-----------------------------------------------------------------------------
1118 CK_DLL_CTRL( stereo_ctrl_pan
)
1120 Chuck_UGen
* ugen
= (Chuck_UGen
* )SELF
;
1121 Chuck_UGen
* left
= ugen
->m_multi_chan
[0];
1122 Chuck_UGen
* right
= ugen
->m_multi_chan
[1];
1124 t_CKFLOAT pan
= GET_CK_FLOAT(ARGS
);
1126 if( pan
< -1.0 ) pan
= -1.0;
1127 else if( pan
> 1.0 ) pan
= 1.0;
1129 OBJ_MEMBER_FLOAT(SELF
, stereo_offset_pan
) = pan
;
1131 left
->m_pan
= pan
< 0.0 ? 1.0 : 1.0 - pan
;
1132 right
->m_pan
= pan
> 0.0 ? 1.0 : 1.0 + pan
;
1134 RETURN
->v_float
= pan
;
1140 //-----------------------------------------------------------------------------
1141 // name: stereo_cget_pan()
1143 //-----------------------------------------------------------------------------
1144 CK_DLL_CGET( stereo_cget_pan
)
1146 RETURN
->v_float
= OBJ_MEMBER_FLOAT(SELF
, stereo_offset_pan
);
1152 //-----------------------------------------------------------------------------
1155 //-----------------------------------------------------------------------------
1156 CK_DLL_TICK( dac_tick
)
1158 *out
= in
; return TRUE
;
1164 //-----------------------------------------------------------------------------
1165 // name: bunghole_tick
1167 //-----------------------------------------------------------------------------
1168 CK_DLL_TICK( bunghole_tick
)
1170 *out
= 0.0f
; return 0;
1176 //-----------------------------------------------------------------------------
1177 // name: noise_tick()
1179 //-----------------------------------------------------------------------------
1180 CK_DLL_TICK( noise_tick
)
1182 *out
= -1.0 + 2.0 * (SAMPLE
)rand() / RAND_MAX
;
1187 enum { NOISE_WHITE
=0, NOISE_PINK
, NOISE_BROWN
, NOISE_FBM
, NOISE_FLIP
, NOISE_XOR
};
1196 t_CKINT
* pink_array
;
1212 scale
= 2.0 / (double) RAND_MAX
;
1215 t_CKINT randt
= RAND_MAX
;
1217 fprob
= (t_CKINT
)( (double)RAND_MAX
* 1.0 / 32.0 );
1218 while ( randt
> 0 ) {
1222 // fprintf(stderr, "random bits - %d", rand_bits );
1229 void tick( t_CKTIME now
, SAMPLE
* out
);
1230 void setMode( const char * c
);
1232 t_CKINT
pink_tick( SAMPLE
* out
);
1233 t_CKINT
brown_tick( SAMPLE
* out
);
1234 t_CKINT
xor_tick( SAMPLE
* out
);
1235 t_CKINT
flip_tick( SAMPLE
* out
);
1236 t_CKINT
fbm_tick( SAMPLE
* out
);
1240 CK_DLL_CTOR( cnoise_ctor
)
1242 OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
) = (t_CKUINT
)new CNoise_Data
;
1245 CK_DLL_DTOR( cnoise_dtor
)
1247 delete (CNoise_Data
*)OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
);
1248 OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
) = 0;
1251 CK_DLL_TICK( cnoise_tick
)
1253 CNoise_Data
* d
= ( CNoise_Data
* )OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
);
1256 return noise_tick(SELF
,in
,out
,SHRED
);
1259 return d
->pink_tick(out
);
1262 return d
->brown_tick(out
);
1265 return d
->xor_tick(out
);
1268 return d
->flip_tick(out
);
1271 return d
->fbm_tick(out
);
1277 t_CKINT
CNoise_Data::pink_tick( SAMPLE
* out
)
1279 //based on Voss-McCartney
1281 if ( pink_array
== NULL
) {
1282 pink_array
= (t_CKINT
*) malloc ( sizeof ( t_CKINT
) * pink_depth
);
1284 for ( t_CKINT i
= 0 ; i
< pink_depth
; i
++ ) { pink_array
[i
] = rand(); last
+= pink_array
[i
]; }
1285 scale
= 2.0 / ((double)RAND_MAX
* ( pink_depth
+ 1.0 ) );
1287 // fprintf( stderr, "scale %f %f %d %d \n", scale, bias, RAND_MAX, pink_depth + 1 );
1292 //count trailing zeroes
1293 while ( pind
< pink_depth
&& ! (counter
& ( 1 << pind
) ) ) pind
++;
1295 // fprintf (stderr, "counter %d pink - %d \n", counter, pind );
1297 if ( pind
< pink_depth
) {
1298 t_CKINT diff
= rand() - pink_array
[pind
];
1299 pink_array
[pind
] += diff
;
1303 *out
= bias
+ scale
* ( rand() + last
);
1305 if ( pink_rand
) counter
= rand();
1309 t_CKINT
CNoise_Data::xor_tick( SAMPLE
* out
)
1312 for ( t_CKINT i
= 0; i
< rand_bits
; i
++ )
1313 if ( rand() <= fprob
)
1316 *out
= bias
+ scale
* (SAMPLE
)last
;
1320 t_CKINT
CNoise_Data::flip_tick( SAMPLE
* out
)
1322 t_CKINT ind
= (t_CKINT
) ( (double) rand_bits
* rand() / ( RAND_MAX
+ 1.0 ) );
1324 last
= last
^ ( 1 << ind
);
1325 // fprintf ( stderr, "ind - %d %d %f %f", ind, last, bias, scale );
1326 *out
= bias
+ scale
* (SAMPLE
)last
;
1331 CNoise_Data::brown_tick( SAMPLE
* out
) {
1332 //brownian noise function..later!
1338 CNoise_Data::fbm_tick( SAMPLE
* out
) {
1339 //non-brownian noise function..later!
1345 CNoise_Data::setMode( const char * c
) {
1346 if ( strcmp ( c
, "white" ) == 0 ) {
1347 // fprintf(stderr, "white noise\n");
1349 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1352 if ( strcmp ( c
, "pink" ) == 0 ) {
1353 // fprintf(stderr, "pink noise\n");
1355 scale
= 2.0 / (double)(RAND_MAX
* ( pink_depth
+ 1 ) );
1358 if ( strcmp ( c
, "flip" ) == 0) {
1359 // fprintf(stderr, "bitflip noise\n");
1361 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1364 if ( strcmp ( c
, "xor" ) == 0) {
1365 // fprintf(stderr, "xor noise\n");
1367 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1370 if ( strcmp ( c
, "brown" ) == 0) {
1371 // fprintf(stderr, "brownian noise\n");
1373 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1376 if ( strcmp ( c
, "fbm" ) == 0) {
1377 // fprintf(stderr, "fbm noise\n");
1379 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1385 CK_DLL_CTRL( cnoise_ctrl_mode
)
1387 CNoise_Data
* d
= ( CNoise_Data
* )OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
);
1388 const char * mode
= (const char *)*(char **)GET_CK_STRING(ARGS
);
1392 CK_DLL_CTRL( cnoise_ctrl_fprob
)
1394 CNoise_Data
* d
= ( CNoise_Data
* )OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
);
1395 t_CKFLOAT p
= GET_CK_FLOAT(ARGS
);
1396 d
->fprob
= (t_CKINT
) ( (double)RAND_MAX
* p
);
1401 //-----------------------------------------------------------------------------
1402 // name: struct Pulse_Data
1404 //-----------------------------------------------------------------------------
1409 Pulse_Data( ) { value
= 1.0f
; when
= 0; }
1413 //-----------------------------------------------------------------------------
1414 // name: impulse_ctor()
1416 //-----------------------------------------------------------------------------
1417 CK_DLL_CTOR( impulse_ctor
)
1419 // return data to be used later
1420 OBJ_MEMBER_UINT(SELF
, impulse_offset_data
) = (t_CKUINT
)new Pulse_Data
;
1426 //-----------------------------------------------------------------------------
1427 // name: impulse_dtor()
1429 //-----------------------------------------------------------------------------
1430 CK_DLL_DTOR( impulse_dtor
)
1433 delete (Pulse_Data
*)OBJ_MEMBER_UINT(SELF
, impulse_offset_data
);
1434 OBJ_MEMBER_UINT(SELF
, impulse_offset_data
) = 0;
1440 //-----------------------------------------------------------------------------
1441 // name: impulse_tick()
1443 //-----------------------------------------------------------------------------
1444 CK_DLL_TICK( impulse_tick
)
1446 Pulse_Data
* d
= (Pulse_Data
*)OBJ_MEMBER_UINT(SELF
, impulse_offset_data
);
1460 //-----------------------------------------------------------------------------
1461 // name: impulse_ctrl_next()
1463 //-----------------------------------------------------------------------------
1464 CK_DLL_CTRL( impulse_ctrl_next
)
1466 Pulse_Data
* d
= (Pulse_Data
*)OBJ_MEMBER_UINT(SELF
, impulse_offset_data
);
1467 d
->value
= (SAMPLE
)GET_CK_FLOAT(ARGS
);
1469 RETURN
->v_float
= (t_CKFLOAT
)d
->value
;
1475 //-----------------------------------------------------------------------------
1476 // name: impulse_cget_next()
1478 //-----------------------------------------------------------------------------
1479 CK_DLL_CGET( impulse_cget_next
)
1481 Pulse_Data
* d
= (Pulse_Data
*)OBJ_MEMBER_UINT(SELF
, impulse_offset_data
);
1482 RETURN
->v_float
= (t_CKFLOAT
)d
->value
;
1488 //-----------------------------------------------------------------------------
1489 // name: step_ctor()
1491 //-----------------------------------------------------------------------------
1492 CK_DLL_CTOR( step_ctor
)
1494 // return data to be used later
1495 OBJ_MEMBER_UINT(SELF
, step_offset_data
) = (t_CKUINT
)new SAMPLE( 1.0f
);
1501 //-----------------------------------------------------------------------------
1502 // name: step_dtor()
1504 //-----------------------------------------------------------------------------
1505 CK_DLL_DTOR( step_dtor
)
1508 delete (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, step_offset_data
);
1509 OBJ_MEMBER_UINT(SELF
, step_offset_data
) = 0;
1513 //-----------------------------------------------------------------------------
1514 // name: step_tick()
1516 //-----------------------------------------------------------------------------
1517 CK_DLL_TICK( step_tick
)
1519 SAMPLE
* d
= (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, step_offset_data
);
1526 //-----------------------------------------------------------------------------
1527 // name: step_ctrl_next()
1529 //-----------------------------------------------------------------------------
1530 CK_DLL_CTRL( step_ctrl_next
)
1532 SAMPLE
* d
= (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, step_offset_data
);
1533 *d
= (SAMPLE
)GET_CK_FLOAT(ARGS
);
1534 RETURN
->v_float
= (t_CKFLOAT
)(*d
);
1538 //-----------------------------------------------------------------------------
1539 // name: step_cget_next()
1541 //-----------------------------------------------------------------------------
1542 CK_DLL_CGET( step_cget_next
)
1544 SAMPLE
* d
= (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, step_offset_data
);
1545 RETURN
->v_float
= (t_CKFLOAT
)(*d
);
1551 //-----------------------------------------------------------------------------
1552 // name: halfrect_tick()
1554 //-----------------------------------------------------------------------------
1555 CK_DLL_TICK( halfrect_tick
)
1557 *out
= in
> 0.0f
? in
: 0.0f
;
1564 //-----------------------------------------------------------------------------
1565 // name: fullrect_tick()
1567 //-----------------------------------------------------------------------------
1568 CK_DLL_TICK( fullrect_tick
)
1570 *out
= in
>= 0.0f
? in
: -in
;
1578 //-----------------------------------------------------------------------------
1579 // name: zerox_ctor()
1581 //-----------------------------------------------------------------------------
1582 CK_DLL_CTOR( zerox_ctor )
1584 OBJ_MEMBER_UINT(SELF, zerox_offset_data) = (t_CKUINT)new SAMPLE( 0.0f );
1588 //-----------------------------------------------------------------------------
1589 // name: zerox_dtor()
1591 //-----------------------------------------------------------------------------
1592 CK_DLL_DTOR( zerox_dtor )
1594 delete (SAMPLE *)OBJ_MEMBER_UINT(SELF, zerox_offset_data);
1595 OBJ_MEMBER_UINT(SELF, zerox_offset_data) = 0;
1599 #define __SGN(x) (x >= 0.0f ? 1.0f : -1.0f )
1600 //-----------------------------------------------------------------------------
1601 // name: zerox_tick()
1603 //-----------------------------------------------------------------------------
1604 CK_DLL_TICK( zerox_tick )
1606 SAMPLE * d = (SAMPLE *)OBJ_MEMBER_UINT(SELF, zerox_offset_data);
1607 *out = __SGN(in) != __SGN(*d);
1626 double readpos
; //readpos ( moves at constant speed, sample per sample
1627 double writepos
; // relative to read position
1629 t_CKTIME offset
; // distance between read and write
1631 t_CKDUR offset_start
;
1632 t_CKDUR offset_target
;
1634 t_CKTIME move_end_time
; //target time
1635 t_CKDUR move_duration
; //time we started shift
1638 t_CKDUR last_offset
;
1651 bufsize
= 2 * g_srate
;
1652 buffer
= ( SAMPLE
* ) realloc ( NULL
, sizeof ( SAMPLE
) * bufsize
);
1655 for ( i
= 0 ; i
< bufsize
; i
++ ) buffer
[i
] = 0;
1656 for ( i
= 0 ; i
< 3 ; i
++ ) { acoeff
[i
] = 0; bcoeff
[i
] = 0; }
1670 offset_target
= 0.0;
1672 move_duration
= 1.0;
1673 move_end_time
= 0.0;
1683 SAFE_DELETE_ARRAY( buffer
);
1687 CK_DLL_CTOR( delayp_ctor
)
1689 OBJ_MEMBER_UINT(SELF
, delayp_offset_data
) = (t_CKUINT
)new delayp_data
;
1692 CK_DLL_DTOR( delayp_dtor
)
1694 delayp_data
* d
= (delayp_data
*)OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1696 OBJ_MEMBER_UINT(SELF
, delayp_offset_data
) = 0;
1699 CK_DLL_PMSG( delayp_pmsg
)
1704 CK_DLL_TICK( delayp_tick
)
1706 delayp_data
* d
= (delayp_data
*)OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1707 if ( !d
->buffer
) return FALSE
;
1710 d
->now
= ((Chuck_UGen
*)SELF
)->shred
->vm_ref
->shreduler()->now_system
;
1712 //calculate new write-offset position ( we interpolate if we've been assigned a new write-offset )
1713 if ( d
->now
>= d
->move_end_time
|| d
->move_duration
== 0 ) d
->offset
= d
->offset_target
;
1715 double dt
= 1.0 + ( d
->now
- d
->move_end_time
) / ( d
->move_duration
);
1716 d
->offset
= d
->offset_start
+ dt
* ( d
->offset_target
- d
->offset_start
);
1717 // fprintf (stderr, "dt %f, off %f , start %f target %f\n", dt, d->writeoff, d->writeoff_start, d->writeoff_target );
1720 //find locations in buffer...
1721 double write
= (d
->readpos
) + d
->offset
;
1722 double last_write
= (d
->readpos
- 1.0) + d
->last_offset
;
1724 //linear interpolation. will introduce some lowpass/aliasing.
1725 double write_delta
= write
- last_write
;
1726 double sample_delta
= in
- d
->last_sample
;
1728 double duck_constant
= 0.69;
1731 double gee
= fabs(write_delta
) - 1.0;
1734 double head_contact
= ( gee
> 0 ) ? exp ( - duck_constant
* gee
) : 1.0;
1735 t_CKINT i
, smin
, smax
, sampi
;
1737 if ( write_delta
>= 0 ) { //forward.
1738 smin
= (t_CKINT
) floor ( last_write
);
1739 smax
= (t_CKINT
) floor ( write
);
1740 for ( i
= smin
+1 ; i
<= smax
; i
++ ) {
1741 sampf
= d
->last_sample
+ sample_delta
* ( double(i
) - last_write
) / write_delta
;
1742 sampi
= ( i
+ d
->bufsize
* 2 ) % d
->bufsize
;
1744 if ( d
->lasti
== sampi
) {
1745 fprintf( stderr
, "[chuck](via Curve): over!\n");
1749 d
->buffer
[sampi
] += sampf
* head_contact
;
1752 else { //moving in reverse
1753 smin
= (t_CKINT
) floor ( write
);
1754 smax
= (t_CKINT
) floor ( last_write
);
1755 for ( i
= smin
+1 ; i
<= smax
; i
++ ) {
1756 sampf
= d
->last_sample
+ sample_delta
* ( double(i
) - last_write
) / write_delta
;
1757 sampi
= ( i
+ d
->bufsize
* 2 ) % d
->bufsize
;
1759 if ( d
->lasti
== sampi
) {
1760 fprintf(stderr
, "[chuck](via Curve): over!\n");
1764 d
->buffer
[sampi
] += sampf
* head_contact
;
1769 d
->last_offset
= d
->offset
;
1770 d
->last_sample
= in
;
1773 //output should go through a dc blocking filter, for cases where
1774 //we are zipping around in the buffer leaving a fairly constant
1777 //output last sample
1779 t_CKINT rpos
= (t_CKINT
) fmod( d
->readpos
, d
->bufsize
) ;
1781 // *out = d->buffer[rpos];
1784 // did i try to write a dc blocking filter?
1785 d->outputs[0] = 0.0;
1786 d->inputs [0] = d->buffer[rpos];
1788 d->outputs[0] += d->bcoeff[1] * d->inputs[1];
1789 d->inputs [1] = d->inputs[0];
1791 d->outputs[0] += d->bcoeff[0] * d->inputs[0];
1793 d->outputs[0] += -d->acoeff[1] * d->outputs[1];
1794 d->outputs[1] = d->outputs[0];
1796 //clear at readpos ( write doesn't !)
1797 *out = d->outputs[0];
1800 *out
= d
->buffer
[rpos
];
1802 d
->buffer
[rpos
] = 0; //clear once it's been read
1803 d
->readpos
= fmod ( d
->readpos
+ 1.0 , double( d
->bufsize
) );
1809 CK_DLL_CTRL( delayp_ctrl_delay
)
1811 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1812 t_CKDUR target
= GET_CK_DUR(ARGS
); // rate
1815 if ( target
!= d
->offset_target
) {
1816 if ( target
> d
->bufsize
) {
1817 fprintf( stderr
, "[chuck](via delayp): delay time %f over max! set max first!\n", target
);
1820 d
->offset_target
= target
;
1821 d
->offset_start
= d
->last_offset
;
1823 t_CKTIME snow
= ((Chuck_UGen
*)SELF
)->shred
->now
;
1824 d
->move_end_time
= snow
+ d
->move_duration
;
1826 RETURN
->v_dur
= d
->last_offset
; // TODO:
1829 CK_DLL_CGET( delayp_cget_delay
)
1831 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1832 //SET_NEXT_DUR( out, d->writeoff_last );
1833 RETURN
->v_dur
= d
->last_offset
; // TODO:
1836 CK_DLL_CTRL( delayp_ctrl_window
)
1838 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1839 t_CKDUR window
= GET_CK_DUR(ARGS
); // rate
1840 if ( window
>= 0 ) {
1841 d
->move_duration
= window
;
1842 //fprintf ( stderr, "set window time %f , %f , %d \n", d->writeoff_window_time, d->writeoff, d->bufsize );
1844 RETURN
->v_dur
= d
->move_duration
; // TODO:
1847 CK_DLL_CGET( delayp_cget_window
)
1849 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1850 RETURN
->v_dur
= d
->move_duration
; // TODO:
1854 CK_DLL_CTRL( delayp_ctrl_max
)
1856 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1857 t_CKDUR nmax
= GET_CK_DUR(ARGS
); // rate
1858 if ( d
->bufsize
!= (t_CKINT
)nmax
&& nmax
> 1.0 ) {
1859 d
->bufsize
= (t_CKINT
)(nmax
+.5);
1860 d
->buffer
= ( SAMPLE
* ) realloc ( d
->buffer
, sizeof ( SAMPLE
) * d
->bufsize
);
1861 for ( t_CKINT i
= 0; i
< d
->bufsize
; i
++ ) d
->buffer
[i
] = 0;
1863 RETURN
->v_dur
= d
->bufsize
; // TODO??
1866 CK_DLL_CGET( delayp_cget_max
)
1868 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1869 //SET_NEXT_DUR( out, (t_CKDUR) d->bufsize );
1870 RETURN
->v_dur
= d
->bufsize
;
1874 #ifndef __DISABLE_SNDBUF__
1876 //-----------------------------------------------------------------------------
1879 //-----------------------------------------------------------------------------
1880 enum { SNDBUF_DROP
= 0, SNDBUF_INTERP
, SNDBUF_SINC
};
1883 #define WIDTH 16 /* this controls the number of neighboring samples
1884 which are used to interpolate the new samples. The
1885 processing time is linearly related to this width */
1886 #define DELAY_SIZE 140
1888 #define USE_TABLE TRUE /* this controls whether a linearly interpolated lookup
1889 table is used for sinc function calculation, or the
1890 sinc is calculated by floating point trig function calls. */
1892 #define USE_INTERP TRUE /* this controls whether the table is linear
1893 interpolated or not. If you re not using the
1894 table, this has no effect */
1896 #define SAMPLES_PER_ZERO_CROSSING 32 /* this defines how finely the sinc function
1897 is sampled for storage in the table */
1899 #ifdef CK_SNDBUF_MEMORY_BUFFER
1900 //------------------------------------------------------------------------------
1901 // name: MultiBuffer
1902 // desc: presents multiple buffers in memory as a single sequential logical
1903 // buffer, for constant time reallocing. tries to be as discreet as possible,
1904 // so you can basically use it like a pointer. optimized for iterative access,
1905 // as random access has T = O(bufsize)
1906 //------------------------------------------------------------------------------
1907 template< class _type
>
1927 void resize( size_t size
)
1929 assert( size
> m_size
); // for now
1930 size_t new_buffer_size
= size
- m_size
;
1933 new_extent
.position
= new _type
[new_buffer_size
];
1934 new_extent
.length
= new_buffer_size
;
1935 m_bufs
.push_back( new_extent
);
1941 // delete everything
1942 size_t i
, len
= m_bufs
.size();
1943 for( i
= 0; i
< len
; i
++ )
1944 delete[] m_bufs
[i
].position
;
1959 Pointer( MultiBuffer
* mb
)
1967 Pointer( const Pointer
& mbp
)\v
1970 m_lpos
= mbp
.m_lpos
;
1971 m_extent
= mbp
.m_extent
;
1972 m_extpos
= mbp
.m_extpos
;
1975 Pointer
& operator=( MultiBuffer
& mb
)
1985 Pointer
& operator=( const Pointer
& mbp
)
1988 m_lpos
= mbp
.m_lpos
;
1989 m_extent
= mbp
.m_extent
;
1990 m_extpos
= mbp
.m_extpos
;
1995 Pointer
& operator=( size_t i
)
2004 return m_mb
->m_bufs
[m_extent
].position
[m_extpos
];
2007 Pointer
operator+( size_t i
) const
2009 Pointer
mbp( *this );
2014 Pointer
operator++( int )
2016 Pointer mbp
= *this;
2017 this->increment( 1 );
2021 bool operator>=( const Pointer
& mbp
) const
2023 return ( m_lpos
>= mbp
.m_lpos
);
2026 bool operator>=( const size_t i
) const
2028 return ( m_lpos
>= i
);
2031 void increment( size_t i
)
2034 if( m_lpos
>= (m_mb
->m_size
) )
2036 m_extent
= m_mb
->m_bufs
.size();
2037 m_extpos
= m_lpos
- m_mb
->m_size
;
2041 extent ext_current
= m_mb
->m_bufs
[m_extent
];
2043 while( i
>= ext_current
.length
)
2045 i
-= ext_current
.length
;
2047 ext_current
= m_mb
->m_bufs
[m_extent
];
2063 size_t m_lpos
; // position in logical buffer
2064 size_t m_extent
; // current extent
2065 size_t m_extpos
; // position within the extent
2076 /* data shared by a set of MultiBuffers */
2077 vector
< extent
> m_bufs
; // array of sequentially allocated buffers
2078 size_t m_size
; // overall size of total memory represented
2080 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2082 // data for each sndbuf
2086 t_CKUINT num_samples
;
2087 t_CKUINT num_channels
;
2088 t_CKUINT num_frames
;
2089 t_CKUINT samplerate
;
2092 t_CKUINT chunks_read
;
2093 t_CKUINT chunks_total
;
2094 t_CKUINT chunks_size
;
2099 t_CKFLOAT sampleratio
;
2101 t_CKFLOAT rate_factor
;
2106 bool sinc_table_built
;
2107 bool sinc_use_table
;
2108 bool sinc_use_interp
;
2109 t_CKINT sinc_samples_per_zero_crossing
;
2111 double * sinc_table
;
2113 #ifdef CK_SNDBUF_MEMORY_BUFFER
2114 MultiBuffer
< SAMPLE
> mb_buffer
;
2115 t_CKUINT mb_max_samples
;
2116 MultiBuffer
< SAMPLE
>::Pointer mb_record_position
;
2117 MultiBuffer
< SAMPLE
>::Pointer mb_playback_position
;
2118 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2126 interp
= SNDBUF_INTERP
;
2144 sinc_table_built
= false;
2145 sinc_use_table
= USE_TABLE
;
2146 sinc_use_interp
= USE_INTERP
;
2148 sinc_samples_per_zero_crossing
= SAMPLES_PER_ZERO_CROSSING
;
2151 #ifdef CK_SNDBUF_MEMORY_BUFFER
2152 mb_buffer
= MultiBuffer
< SAMPLE
>();
2153 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2161 SAFE_DELETE_ARRAY( buffer
);
2162 SAFE_DELETE_ARRAY( chunk_table
);
2167 double sndbuf_sinc( sndbuf_data
* d
, double x
);
2168 double sndbuf_t_sinc( sndbuf_data
* d
, double x
);
2169 void sndbuf_make_sinc( sndbuf_data
* d
);
2170 void sndbuf_sinc_interpolate( sndbuf_data
* d
, SAMPLE
* out
);
2172 CK_DLL_CTOR( sndbuf_ctor
)
2174 OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
) = (t_CKUINT
)new sndbuf_data
;
2177 CK_DLL_DTOR( sndbuf_dtor
)
2179 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2181 OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
) = 0;
2184 inline t_CKUINT
sndbuf_read( sndbuf_data
* d
, t_CKUINT offset
, t_CKUINT howmuch
)
2187 if( d
->fd
== NULL
) return 0;
2188 if( offset
>= d
->num_frames
) return 0;
2191 // EM_log( CK_LOG_FINE, "(sndbuf): reading %d:%d frames...", offset, howmuch );
2194 if( howmuch
> d
->num_frames
- offset
)
2195 howmuch
= d
->num_frames
- offset
;
2199 sf_seek( d
->fd
, offset
, SEEK_SET
);
2200 #if defined(CK_S_DOUBLE)
2201 n
= sf_readf_double( d
->fd
, d
->buffer
+offset
*d
->num_channels
, howmuch
);
2203 n
= sf_readf_float( d
->fd
, d
->buffer
+offset
*d
->num_channels
, howmuch
);
2206 d
->chunks_read
+= n
;
2209 if( d
->chunks_read
>= d
->num_frames
)
2212 EM_log( CK_LOG_INFO
, "(sndbuf): all frames read, closing file..." );
2220 inline t_CKINT
sndbuf_load( sndbuf_data
* d
, t_CKUINT where
)
2223 t_CKUINT bin
= (t_CKUINT
)(where
/ (t_CKFLOAT
)d
->chunks_size
);
2224 if( bin
>= d
->chunks_total
) return 0;
2227 if( d
->chunk_table
[bin
] ) return 0;
2230 t_CKINT ret
= sndbuf_read( d
, bin
*d
->chunks_size
, d
->chunks_size
);
2233 d
->chunk_table
[bin
] = true;
2236 // EM_log( CK_LOG_FINER, "chunk test: pos: %d bin: %d read:%d/%d", where, bin, d->chunks_read, d->num_frames );
2241 inline void sndbuf_setpos( sndbuf_data
*d
, double pos
)
2243 if( !d
->buffer
) return;
2247 // set curf within bounds
2250 while( d
->curf
>= d
->num_frames
) d
->curf
-= d
->num_frames
;
2251 while( d
->curf
< 0 ) d
->curf
+= d
->num_frames
;
2255 if( d
->curf
< 0 ) d
->curf
= 0;
2256 else if( d
->curf
>= d
->num_frames
) d
->curf
= d
->num_frames
;
2259 t_CKINT i
= (t_CKINT
)d
->curf
;
2261 if( d
->fd
!= NULL
) sndbuf_load( d
, i
);
2262 // sets curr to correct position ( account for channels )
2263 d
->curr
= d
->buffer
+ d
->chan
+ i
* d
->num_channels
;
2266 inline SAMPLE
sndbuf_sampleAt( sndbuf_data
* d
, t_CKINT pos
)
2269 t_CKINT nf
= d
->num_frames
;
2271 while( pos
> nf
) pos
-= nf
;
2272 while( pos
< 0 ) pos
+= nf
;
2275 if( pos
> nf
) pos
= nf
;
2276 if( pos
< 0 ) pos
= 0;
2279 t_CKUINT index
= d
->chan
+ pos
* d
->num_channels
;
2281 if( d
->fd
!= NULL
) sndbuf_load( d
, pos
);
2283 return d
->buffer
[index
];
2286 inline double sndbuf_getpos( sndbuf_data
* d
)
2288 if( !d
->buffer
) return 0;
2289 return floor(d
->curf
);
2292 CK_DLL_CTRL( sndbuf_ctrl_loop
)
2294 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2295 d
->loop
= GET_CK_INT(ARGS
);
2296 RETURN
->v_int
= d
->loop
; // TODO: Check (everything)
2299 CK_DLL_CGET( sndbuf_cget_loop
)
2301 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2302 RETURN
->v_int
= d
->loop
;
2305 // PRC's sinc interpolation function.. as found
2306 // http://www.cs.princeton.edu/courses/archive/spring03/cs325/src/TimeStuf/srconvrt.c
2308 // there's probably a lot in there that could be optimized, if we care to..
2310 // #define PI 3.14159265358979323846
2311 // wow... we are sensitive..
2313 inline double sndbuf_linear_interp( double * first
, double * second
, double * frac
);
2314 bool sinc_table_built
= false;
2316 void sndbuf_sinc_interpolate( sndbuf_data
*d
, SAMPLE
* out
)
2319 double factor
= d
->rate
;
2320 double time_now
= d
->curf
;
2321 double one_over_factor
;
2322 // UNUSED: double int_time = 0;
2323 // UNUSED: double last_time = 0;
2326 long time_i
= (long)time_now
;
2328 // bounds checking now in sampleAt function...
2329 if( factor
< 1.0 ) {
2330 for( j
= -d
->sinc_width
+ 1; j
< d
->sinc_width
; j
++ )
2332 temp1
+= sndbuf_sampleAt(d
,time_i
+j
) * sndbuf_sinc( d
, (double)j
);
2334 *out
= (SAMPLE
)temp1
;
2337 one_over_factor
= 1.0 / factor
;
2338 for( j
= -d
->sinc_width
+ 1; j
< d
->sinc_width
; j
++ ) {
2339 temp1
+= sndbuf_sampleAt(d
,time_i
+j
) * one_over_factor
* sndbuf_sinc( d
, one_over_factor
* (double)j
);
2341 *out
= (SAMPLE
)temp1
;
2345 void sndbuf_make_sinc( sndbuf_data
* d
)
2348 // fprintf(stderr, "building sinc table\n" );
2349 double temp
, win_freq
, win
;
2350 win_freq
= ONE_PI
/ d
->sinc_width
/ d
->sinc_samples_per_zero_crossing
;
2351 t_CKINT tabsize
= d
->sinc_width
* d
->sinc_samples_per_zero_crossing
;
2353 d
->sinc_table
= (double *) realloc( d
->sinc_table
, tabsize
* sizeof(double) );
2354 d
->sinc_table
[0] = 1.0;
2355 for( i
= 1; i
< tabsize
; i
++ ) {
2356 temp
= (double) i
* ONE_PI
/ d
->sinc_samples_per_zero_crossing
;
2357 d
->sinc_table
[i
] = (float)(sin(temp
) / temp
);
2358 win
= 0.5 + 0.5 * cos(win_freq
* i
);
2359 d
->sinc_table
[i
] *= (float)win
;
2361 d
->sinc_table_built
= true;
2364 inline double sndbuf_linear_interp( double first_number
, double second_number
, double fraction
)
2366 return (first_number
+ ((second_number
- first_number
) * fraction
));
2369 double sndbuf_t_sinc( sndbuf_data
* d
, double x
)
2373 if( !d
->sinc_table_built
) sndbuf_make_sinc(d
);
2374 if( fabs(x
) >= d
->sinc_width
-1 )
2377 temp
= fabs(x
) * (double) d
->sinc_samples_per_zero_crossing
;
2378 low
= (t_CKINT
)temp
; /* these are interpolation steps */
2379 if( d
->sinc_use_interp
) {
2380 delta
= temp
- low
; /* and can be ommited if desired */
2381 return sndbuf_linear_interp( d
->sinc_table
[low
], d
->sinc_table
[low
+ 1], delta
);
2383 else return d
->sinc_table
[low
];
2387 double sndbuf_sinc( sndbuf_data
* d
, double x
)
2391 if( d
->sinc_use_table
) return sndbuf_t_sinc(d
,x
);
2393 if( x
== 0.0 ) return 1.0;
2396 return sin(temp
) / (temp
);
2401 CK_DLL_TICK( sndbuf_tick
)
2403 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2405 #ifdef CK_SNDBUF_MEMORY_BUFFER
2406 // spencer's memory buffer stuff
2408 // no file open - memory buffer mode
2410 Chuck_UGen
* ugen
= (Chuck_UGen
*)SELF
;
2411 if( ugen
->m_num_src
)
2414 if( d
->mb_buffer
.size() == 0 )
2416 d
->mb_buffer
.resize( 44100 * 4 ); // default size: 4 seconds
2417 d
->mb_record_position
= d
->mb_buffer
;
2418 d
->mb_playback_position
= d
->mb_buffer
;
2421 if( d
->mb_record_position
>= d
->mb_buffer
.size() )
2422 d
->mb_buffer
.resize( d
->mb_buffer
.size() * 2 );
2424 *(d
->mb_record_position
++) = in
;
2427 if( d
->mb_buffer
.size() )
2429 if( d
->mb_playback_position
>= d
->mb_record_position
)
2432 d
->mb_playback_position
= 0;
2434 else if( ugen
->m_num_src
)
2444 *out
= *(d
->mb_playback_position
++);
2449 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2450 if( !d
->buffer
) return FALSE
;
2452 // we're ticking once per sample ( system )
2455 if( !d
->loop
&& d
->curr
>= d
->eob
+ d
->num_channels
) return FALSE
;
2458 if( d
->interp
== SNDBUF_DROP
)
2460 *out
= (SAMPLE
)( (*(d
->curr
)) ) ;
2462 else if( d
->interp
== SNDBUF_INTERP
)
2464 // samplewise linear interp
2465 double alpha
= d
->curf
- floor(d
->curf
);
2466 *out
= (SAMPLE
)( (*(d
->curr
)) ) ;
2467 *out
+= (float)alpha
* ( sndbuf_sampleAt(d
, (long)d
->curf
+1 ) - *out
);
2469 else if( d
->interp
== SNDBUF_SINC
) {
2470 // do that fancy sinc function!
2471 sndbuf_sinc_interpolate(d
, out
);
2476 sndbuf_setpos(d
, d
->curf
);
2482 #include "util_raw.h"
2485 CK_DLL_CTRL( sndbuf_ctrl_read
)
2487 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2488 const char * filename
= GET_CK_STRING(ARGS
)->str
.c_str();
2492 delete [] d
->buffer
;
2496 if( d
->chunk_table
)
2498 delete [] d
->chunk_table
;
2499 d
->chunk_table
= NULL
;
2509 EM_log( CK_LOG_INFO
, "(sndbuf): reading '%s'...", filename
);
2512 if( strstr(filename
, "special:") )
2514 SAMPLE
* rawdata
= NULL
;
2515 t_CKUINT rawsize
= 0;
2516 t_CKUINT srate
= 22050;
2519 if( strstr(filename
, "special:sinewave") ) {
2520 rawsize
= 1024; rawdata
= NULL
;
2522 else if( strstr(filename
, "special:ahh") ) {
2523 rawsize
= ahh_size
; rawdata
= ahh_data
;
2525 else if( strstr(filename
, "special:britestk") ) {
2526 rawsize
= britestk_size
; rawdata
= britestk_data
;
2528 else if( strstr(filename
, "special:dope") ) {
2529 rawsize
= dope_size
; rawdata
= dope_data
;
2531 else if( strstr(filename
, "special:eee") ) {
2532 rawsize
= eee_size
; rawdata
= eee_data
;
2534 else if( strstr(filename
, "special:fwavblnk") ) {
2535 rawsize
= fwavblnk_size
; rawdata
= fwavblnk_data
;
2537 else if( strstr(filename
, "special:halfwave") ) {
2538 rawsize
= halfwave_size
; rawdata
= halfwave_data
;
2540 else if( strstr(filename
, "special:impuls10") ) {
2541 rawsize
= impuls10_size
; rawdata
= impuls10_data
;
2543 else if( strstr(filename
, "special:impuls20") ) {
2544 rawsize
= impuls20_size
; rawdata
= impuls20_data
;
2546 else if( strstr(filename
, "special:impuls40") ) {
2547 rawsize
= impuls40_size
; rawdata
= impuls40_data
;
2549 else if( strstr(filename
, "special:mand1") ) {
2550 rawsize
= mand1_size
; rawdata
= mand1_data
;
2552 else if( strstr(filename
, "special:mandpluk") ) {
2553 rawsize
= mandpluk_size
; rawdata
= mandpluk_data
;
2555 else if( strstr(filename
, "special:marmstk1") ) {
2556 rawsize
= marmstk1_size
; rawdata
= marmstk1_data
;
2558 else if( strstr(filename
, "special:ooo") ) {
2559 rawsize
= ooo_size
; rawdata
= ooo_data
;
2561 else if( strstr(filename
, "special:peksblnk") ) {
2562 rawsize
= peksblnk_size
; rawdata
= peksblnk_data
;
2564 else if( strstr(filename
, "special:ppksblnk") ) {
2565 rawsize
= ppksblnk_size
; rawdata
= ppksblnk_data
;
2567 else if( strstr(filename
, "special:silence") ) {
2568 rawsize
= silence_size
; rawdata
= silence_data
;
2570 else if( strstr(filename
, "special:sineblnk") ) {
2571 rawsize
= sineblnk_size
; rawdata
= sineblnk_data
;
2573 else if( strstr(filename
, "special:sinewave") ) {
2574 rawsize
= sinewave_size
; rawdata
= sinewave_data
;
2576 else if( strstr(filename
, "special:snglpeak") ) {
2577 rawsize
= snglpeak_size
; rawdata
= snglpeak_data
;
2579 else if( strstr(filename
, "special:twopeaks") ) {
2580 rawsize
= twopeaks_size
; rawdata
= twopeaks_data
;
2582 else if( strstr(filename
, "special:glot_ahh") ) {
2583 rawsize
= glot_ahh_size
; rawdata
= glot_ahh_data
; srate
= 44100;
2585 else if( strstr(filename
, "special:glot_eee") ) {
2586 rawsize
= glot_eee_size
; rawdata
= glot_eee_data
; srate
= 44100;
2588 else if( strstr(filename
, "special:glot_ooo") ) {
2589 rawsize
= glot_ooo_size
; rawdata
= glot_ooo_data
; srate
= 44100;
2591 else if( strstr(filename
, "special:glot_pop") ) {
2592 rawsize
= glot_pop_size
; rawdata
= glot_pop_data
; srate
= 44100;
2595 d
->num_frames
= rawsize
;
2596 d
->num_channels
= 1;
2598 d
->samplerate
= srate
;
2599 d
->num_samples
= rawsize
;
2602 d
->chunks_read
= d
->num_frames
;
2605 d
->buffer
= new SAMPLE
[rawsize
+1];
2606 for( t_CKUINT j
= 0; j
< rawsize
; j
++ ) {
2607 d
->buffer
[j
] = (SAMPLE
)rawdata
[j
]/(SAMPLE
)SHRT_MAX
;
2610 else if( strstr(filename
, "special:sinewave") ) {
2611 d
->buffer
= new SAMPLE
[rawsize
+1];
2612 for( t_CKUINT j
= 0; j
< rawsize
; j
++ )
2613 d
->buffer
[j
] = sin(2*ONE_PI
*j
/rawsize
);
2616 fprintf( stderr
, "[chuck](via SndBuf): cannot load '%s'\n", filename
);
2620 d
->buffer
[rawsize
] = d
->buffer
[0];
2624 // stat the file first
2626 if( stat( filename
, &s
) )
2628 fprintf( stderr
, "[chuck](via SndBuf): cannot stat file '%s'...\n", filename
);
2635 const char * format
= (const char *)strrchr( filename
, '.');
2636 if( format
&& strcmp( format
, ".raw" ) == 0 )
2638 fprintf( stderr
, "[chuck](via SndBuf) %s :: type is '.raw'...\n assuming 16 bit signed mono (PCM)\n", filename
);
2639 info
.format
= SF_FORMAT_RAW
| SF_FORMAT_PCM_16
| SF_ENDIAN_CPU
;
2641 info
.samplerate
= 44100;
2645 d
->fd
= sf_open( filename
, SFM_READ
, &info
);
2646 t_CKINT er
= sf_error( d
->fd
);
2649 fprintf( stderr
, "[chuck](via SndBuf): sndfile error '%i' opening '%s'...\n", er
, filename
);
2650 fprintf( stderr
, "[chuck](via SndBuf): (reason: %s)\n", sf_strerror( d
->fd
) );
2651 if( d
->fd
) sf_close( d
->fd
);
2657 t_CKINT size
= info
.channels
* info
.frames
;
2658 d
->buffer
= new SAMPLE
[size
+info
.channels
];
2659 memset( d
->buffer
, 0, (size
+info
.channels
)*sizeof(SAMPLE
) );
2661 d
->num_frames
= info
.frames
;
2662 d
->num_channels
= info
.channels
;
2663 d
->samplerate
= info
.samplerate
;
2664 d
->num_samples
= size
;
2668 EM_log( CK_LOG_INFO
, "channels: %d", d
->num_channels
);
2669 EM_log( CK_LOG_INFO
, "frames: %d", d
->num_frames
);
2670 EM_log( CK_LOG_INFO
, "srate: %d", d
->samplerate
);
2671 EM_log( CK_LOG_INFO
, "chunks: %d", d
->chunks
);
2675 sf_seek( d
->fd
, 0, SEEK_SET
);
2682 t_CKUINT f
= sndbuf_read( d
, 0, d
->num_frames
);
2684 if( f
!= (t_CKUINT
)d
->num_frames
)
2686 fprintf( stderr
, "[chuck](via SndBuf): read %d rather than %d frames from %s\n",
2687 f
, size
, filename
);
2688 sf_close( d
->fd
); d
->fd
= NULL
;
2692 assert( d
->fd
== NULL
);
2697 d
->chunks_size
= d
->chunks
;
2698 d
->chunks_total
= d
->num_frames
/ d
->chunks
;
2699 d
->chunks_total
+= d
->num_frames
% d
->chunks
? 1 : 0;
2701 d
->chunk_table
= new bool[d
->chunks_total
];
2702 memset( d
->chunk_table
, 0, d
->chunks_total
* sizeof(bool) );
2705 // sndbuf_load( d, 0 );
2709 // d->interp = SNDBUF_INTERP;
2710 d
->sampleratio
= (double)d
->samplerate
/ (double)g_srate
;
2712 d
->rate
= d
->sampleratio
* d
->rate_factor
;
2713 d
->curr
= d
->buffer
;
2715 d
->eob
= d
->buffer
+ d
->num_samples
;
2718 CK_DLL_CTRL( sndbuf_ctrl_write
)
2720 #ifdef SPENCER_SNDBUF_WRITE
2721 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2722 const char * filename
= GET_CK_STRING(ARGS
)->str
.c_str();
2726 delete [] d
->buffer
;
2731 if( stat( filename
, &s
) )
2733 fprintf( stderr
, "[chuck](via SndBuf): cannot stat file '%s'...\n", filename
);
2737 d
->curr
= d
->buffer
;
2738 d
->eob
= d
->buffer
+ d
->num_samples
;
2743 CK_DLL_CTRL( sndbuf_ctrl_rate
)
2745 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2746 t_CKFLOAT rate
= GET_CK_FLOAT(ARGS
); // rate
2747 d
->rate
= rate
* d
->sampleratio
;
2748 d
->rate_factor
= rate
;
2749 RETURN
->v_float
= d
->rate_factor
; // TODO: (or not TODO:)
2752 CK_DLL_CGET( sndbuf_cget_rate
)
2754 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2755 RETURN
->v_float
= d
->rate_factor
;
2759 CK_DLL_CTRL( sndbuf_ctrl_freq
)
2761 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2762 t_CKFLOAT freq
= GET_CK_FLOAT(ARGS
); //hz
2764 d
->rate
= ( freq
* (double) d
->num_frames
/ (double) g_srate
);
2765 d
->rate_factor
= d
->rate
/ d
->sampleratio
;
2766 RETURN
->v_float
= d
->rate
* (t_CKFLOAT
) g_srate
/ ( (t_CKFLOAT
) d
->num_frames
); // TODO: really?
2769 CK_DLL_CGET( sndbuf_cget_freq
)
2771 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2772 RETURN
->v_float
= d
->rate
* (t_CKFLOAT
) g_srate
/ ( (t_CKFLOAT
) d
->num_frames
);
2775 CK_DLL_CTRL( sndbuf_ctrl_phase
)
2777 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2778 t_CKFLOAT phase
= GET_CK_FLOAT(ARGS
);
2779 sndbuf_setpos(d
, phase
* (double)d
->num_frames
);
2780 RETURN
->v_float
= (t_CKFLOAT
) d
->curf
/ (t_CKFLOAT
)d
->num_frames
; // TODO:
2783 CK_DLL_CGET( sndbuf_cget_phase
)
2785 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2786 //SET_NEXT_FLOAT( out, (t_CKFLOAT) d->curf / (t_CKFLOAT)d->num_frames );
2787 RETURN
->v_float
= (t_CKFLOAT
) d
->curf
/ (t_CKFLOAT
)d
->num_frames
;
2790 CK_DLL_CTRL( sndbuf_ctrl_channel
)
2792 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2793 unsigned long chan
= (unsigned long)GET_CK_INT(ARGS
);
2794 if ( chan
>= 0 && chan
< d
->num_channels
) {
2797 RETURN
->v_int
= (t_CKINT
)d
->chan
;
2800 CK_DLL_CGET( sndbuf_cget_channel
)
2802 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2803 //SET_NEXT_INT( out, d->chan );
2804 RETURN
->v_int
= (t_CKINT
)d
->chan
;
2807 CK_DLL_CTRL( sndbuf_ctrl_pos
)
2809 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2810 t_CKINT pos
= GET_CK_INT(ARGS
);
2811 #ifdef CK_SNDBUF_MEMORY_BUFFER
2812 if( pos
>= 0 && pos
< d
->mb_max_samples
)
2813 d
->mb_playback_position
= pos
;
2814 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2815 sndbuf_setpos(d
, pos
);
2816 RETURN
->v_int
= (t_CKINT
)sndbuf_getpos(d
); // TODO TODO TODOOO
2819 CK_DLL_CGET( sndbuf_cget_pos
)
2821 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2822 RETURN
->v_int
= (t_CKINT
)sndbuf_getpos(d
);
2825 CK_DLL_CTRL( sndbuf_ctrl_interp
)
2827 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2828 t_CKINT interp
= GET_CK_INT(ARGS
);
2830 RETURN
->v_int
= d
->interp
;
2833 CK_DLL_CGET( sndbuf_cget_interp
)
2835 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2836 RETURN
->v_int
= d
->interp
;
2839 CK_DLL_CTRL( sndbuf_ctrl_chunks
)
2841 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2842 t_CKINT frames
= GET_NEXT_INT(ARGS
);
2843 d
->chunks
= frames
>= 0 ? frames
: 0;
2844 RETURN
->v_int
= d
->chunks
;
2847 CK_DLL_CGET( sndbuf_cget_chunks
)
2849 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2850 RETURN
->v_int
= d
->chunks
;
2853 CK_DLL_CTRL( sndbuf_ctrl_phase_offset
)
2855 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2856 t_CKFLOAT phase_offset
= GET_CK_FLOAT(ARGS
);
2857 sndbuf_setpos(d
, d
->curf
+ phase_offset
* (t_CKFLOAT
)d
->num_frames
);
2860 CK_DLL_CGET( sndbuf_cget_samples
)
2862 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2863 //SET_NEXT_INT( out, d->num_frames );
2864 RETURN
->v_int
= d
->num_frames
;
2867 CK_DLL_CGET( sndbuf_cget_length
)
2869 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2870 //SET_NEXT_DUR( out, (t_CKDUR)d->num_frames );
2871 RETURN
->v_dur
= (t_CKDUR
)d
->num_frames
/ d
->sampleratio
;
2874 CK_DLL_CGET( sndbuf_cget_channels
)
2876 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2877 //SET_NEXT_INT( out, d->num_channels );
2878 RETURN
->v_int
= d
->num_channels
;
2881 CK_DLL_CGET( sndbuf_cget_valueAt
)
2883 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2884 t_CKINT i
= GET_CK_INT(ARGS
);
2885 if( d
->fd
) sndbuf_load( d
, i
);
2886 RETURN
->v_float
= ( i
> d
->num_frames
|| i
< 0 ) ? 0 : d
->buffer
[i
];
2889 #endif // __DISABLE_SNDBUF__
2895 const static t_CKDUR ms
;
2898 t_CKFLOAT slopeAbove
;
2899 t_CKFLOAT slopeBelow
;
2903 t_CKFLOAT xd
; //sidechain
2904 int externalSideInput
; // use input signal or a ctrl signal for env
2905 t_CKFLOAT sideInput
; // the ctrl signal for the envelope
2907 int count
; //diagnostic
2923 //set the time constants for rt, at, and tav
2924 static t_CKFLOAT
computeTimeConst(t_CKDUR t
) {
2925 //AT = 1 - e ^ (-2.2T/t<AT)
2926 //as per chuck_type.cpp, T(sampling period) = 1.0
2927 return 1.0 - exp( -2.2 / t
);
2930 static t_CKDUR
timeConstToDur(t_CKFLOAT x
) {
2931 return -2.2 / log(1.0 - x
);
2934 //setters for timing constants
2935 void setAttackTime(t_CKDUR t
);
2936 void setReleaseTime(t_CKDUR t
);
2939 void setRatio(t_CKFLOAT newRatio
);
2940 t_CKFLOAT
getRatio();
2943 const t_CKDUR
Dyno_Data::ms
= g_vm
->srate() * 1.0 / 1000.0;
2945 //setters for the timing constants
2946 void Dyno_Data::setAttackTime(t_CKDUR t
) {
2947 at
= computeTimeConst(t
);
2950 void Dyno_Data::setReleaseTime(t_CKDUR t
) {
2951 rt
= computeTimeConst(t
);
2954 void Dyno_Data::setRatio(t_CKFLOAT newRatio
) {
2955 this->slopeAbove
= 1.0 / newRatio
;
2956 this->slopeBelow
= 1.0;
2959 t_CKFLOAT
Dyno_Data::getRatio()
2961 return this->slopeBelow
/ this->slopeAbove
;
2964 //TODO: come up with better/good presets?
2966 //presets for the dynomics processor
2967 void Dyno_Data::limit() {
2968 slopeAbove
= 0.1; // 10:1 compression above thresh
2969 slopeBelow
= 1.0; // no compression below
2971 at
= computeTimeConst( 5.0 * ms
);
2972 rt
= computeTimeConst( 300.0 * ms
);
2973 externalSideInput
= 0;
2976 void Dyno_Data::compress() {
2977 slopeAbove
= 0.5; // 2:1 compression
2980 at
= computeTimeConst( 5.0 * ms
);
2981 rt
= computeTimeConst( 500.0 * ms
);
2982 externalSideInput
= 0;
2985 void Dyno_Data::gate() {
2987 slopeBelow
= 100000000; // infinity (more or less)
2989 at
= computeTimeConst( 11.0 * ms
);
2990 rt
= computeTimeConst( 100.0 * ms
);
2991 externalSideInput
= 0;
2994 void Dyno_Data::expand() {
2995 slopeAbove
= 2.0; // 1:2 expansion
2998 at
= computeTimeConst( 20.0 * ms
);
2999 rt
= computeTimeConst( 400.0 * ms
);
3000 externalSideInput
= 0;
3003 void Dyno_Data::duck() {
3004 slopeAbove
= 0.5; // when sideInput rises above thresh, gain starts going
3005 slopeBelow
= 1.0; // down. it'll drop more as sideInput gets louder.
3007 at
= computeTimeConst( 10.0 * ms
);
3008 rt
= computeTimeConst( 1000.0 * ms
);
3009 externalSideInput
= 1;
3013 //controls for the preset modes
3014 CK_DLL_CTRL( dyno_ctrl_limit
) {
3015 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3019 CK_DLL_CTRL( dyno_ctrl_compress
) {
3020 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3024 CK_DLL_CTRL( dyno_ctrl_gate
) {
3025 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3029 CK_DLL_CTRL( dyno_ctrl_expand
) {
3030 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3034 CK_DLL_CTRL( dyno_ctrl_duck
) {
3035 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3039 //additional controls: thresh
3040 CK_DLL_CTRL( dyno_ctrl_thresh
) {
3041 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3042 d
->thresh
= GET_CK_FLOAT(ARGS
);
3043 RETURN
->v_float
= (t_CKFLOAT
)d
->thresh
;
3046 CK_DLL_CGET( dyno_cget_thresh
) {
3047 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3048 RETURN
->v_float
= (t_CKFLOAT
)d
->thresh
;
3051 //additional controls: attackTime
3052 CK_DLL_CTRL( dyno_ctrl_attackTime
) {
3053 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3054 d
->setAttackTime( GET_CK_FLOAT(ARGS
) );
3055 RETURN
->v_dur
= d
->timeConstToDur(d
->at
);
3058 CK_DLL_CGET( dyno_cget_attackTime
) {
3059 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3060 RETURN
->v_dur
= d
->timeConstToDur(d
->at
);
3063 //additional controls: releaseTime
3064 CK_DLL_CTRL( dyno_ctrl_releaseTime
) {
3065 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3066 d
->setReleaseTime( GET_CK_FLOAT(ARGS
) );
3067 RETURN
->v_dur
= d
->timeConstToDur(d
->rt
);
3070 CK_DLL_CGET( dyno_cget_releaseTime
) {
3071 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3072 RETURN
->v_dur
= d
->timeConstToDur(d
->rt
);
3075 //additional controls: ratio
3076 CK_DLL_CTRL( dyno_ctrl_ratio
) {
3077 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3078 d
->setRatio( GET_CK_FLOAT(ARGS
) );
3079 RETURN
->v_float
= d
->getRatio();
3082 CK_DLL_CGET( dyno_cget_ratio
) {
3083 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3084 RETURN
->v_float
= d
->getRatio();
3087 //additional controls: slopeBelow
3088 CK_DLL_CTRL( dyno_ctrl_slopeBelow
) {
3089 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3090 d
->slopeBelow
= GET_CK_FLOAT(ARGS
);
3092 RETURN
->v_float
= d
->slopeBelow
;
3095 CK_DLL_CGET( dyno_cget_slopeBelow
) {
3096 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3097 RETURN
->v_float
= d
->slopeBelow
;
3100 //additional controls: slopeAbove
3101 CK_DLL_CTRL( dyno_ctrl_slopeAbove
) {
3102 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3103 d
->slopeAbove
= GET_CK_FLOAT(ARGS
);
3105 RETURN
->v_float
= d
->slopeAbove
;
3108 CK_DLL_CGET( dyno_cget_slopeAbove
) {
3109 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3110 RETURN
->v_float
= d
->slopeAbove
;
3113 //additional controls: sideInput
3114 CK_DLL_CTRL( dyno_ctrl_sideInput
) {
3115 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3116 d
->sideInput
= GET_CK_FLOAT(ARGS
);
3118 RETURN
->v_float
= d
->sideInput
;
3121 CK_DLL_CGET( dyno_cget_sideInput
) {
3122 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3123 RETURN
->v_float
= d
->sideInput
;
3126 //additional controls: externalSideInput
3127 CK_DLL_CTRL( dyno_ctrl_externalSideInput
) {
3128 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3129 d
->externalSideInput
= GET_CK_INT(ARGS
);
3131 RETURN
->v_int
= d
->externalSideInput
;
3134 CK_DLL_CGET( dyno_cget_externalSideInput
) {
3135 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3136 RETURN
->v_int
= d
->externalSideInput
;
3140 CK_DLL_CTOR( dyno_ctor
)
3142 OBJ_MEMBER_UINT(SELF
, dyno_offset_data
) = (t_CKUINT
)new Dyno_Data
;
3145 CK_DLL_DTOR( dyno_dtor
)
3147 delete (Dyno_Data
*)OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3148 OBJ_MEMBER_UINT(SELF
, dyno_offset_data
) = 0;
3151 // recomputes envelope, determines how the current amp envelope compares with
3152 // thresh, applies the appropriate new slope depending on how far above/below
3153 // the threshold the current envelope is.
3154 CK_DLL_TICK( dyno_tick
)
3156 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3158 // only change sideInput if we're not using an external ctrl signal.
3159 // otherwise we'll just use whatever the user sent us last as the ctrl signal
3160 if(!d
->externalSideInput
)
3161 d
->sideInput
= in
>= 0 ? in
: -in
;
3163 // 'a' is signal left after subtracting xd (to recompute sideChain envelope)
3164 double a
= d
->sideInput
- d
->xd
;
3165 // a is only needed if positive to pull the envelope up, not to bring it down
3167 // the attack/release (peak) exponential filter to guess envelope
3168 d
->xd
= d
->xd
* (1 - d
->rt
) + d
->at
* a
;
3170 // if you were to use the rms filter,
3171 // it would probably look, a sumpthin' like this
3172 // d->xd = TAV * in*in + (1+TAV) * d->xd
3174 // decide which slope to use, depending on whether we're below/above thresh
3175 double slope
= d
->xd
> d
->thresh
? d
->slopeAbove
: d
->slopeBelow
;
3176 // the gain function - apply the slope chosen above
3177 double f
= slope
== 1.0 ? 1.0 : pow( d
->xd
/ d
->thresh
, slope
- 1.0 );
3179 // apply the gain found above to input sample
3188 #define LiSa_MAXVOICES 200
3189 #define LiSa_MAXBUFSIZE 44100000
3190 //-----------------------------------------------------------------------------
3191 // name: LiSaMulti_data
3193 //-----------------------------------------------------------------------------
3194 struct LiSaMulti_data
3199 t_CKINT loop_start
[LiSa_MAXVOICES
], loop_end
[LiSa_MAXVOICES
], loop_end_rec
;
3200 t_CKINT rindex
; // record and play indices
3201 t_CKBOOL record
, looprec
, loopplay
[LiSa_MAXVOICES
], reset
, append
, play
[LiSa_MAXVOICES
], bi
[LiSa_MAXVOICES
];
3202 t_CKFLOAT coeff
; // feedback coeff
3203 t_CKFLOAT voiceGain
[LiSa_MAXVOICES
]; //gain control for each voice
3204 t_CKDOUBLE p_inc
[LiSa_MAXVOICES
], pindex
[LiSa_MAXVOICES
]; // playback increment
3207 t_CKDOUBLE rampup_len
[LiSa_MAXVOICES
], rampdown_len
[LiSa_MAXVOICES
], rec_ramplen
, rec_ramplen_inv
;
3208 t_CKDOUBLE rampup_len_inv
[LiSa_MAXVOICES
], rampdown_len_inv
[LiSa_MAXVOICES
];
3209 t_CKDOUBLE rampctr
[LiSa_MAXVOICES
];
3210 t_CKBOOL rampup
[LiSa_MAXVOICES
], rampdown
[LiSa_MAXVOICES
];
3214 // allocate memory, length in samples
3215 inline int buffer_alloc(t_CKINT length
)
3217 mdata
= (SAMPLE
*)malloc((length
+ 1) * sizeof(SAMPLE
)); //extra sample for safety....
3219 fprintf(stderr
, "LiSaBasic: unable to allocate memory!\n");
3224 maxvoices
= 10; // default; user can set
3226 rec_ramplen_inv
= 1.;
3230 for (t_CKINT i
=0; i
< LiSa_MAXVOICES
; i
++) {
3232 loop_end
[i
] = length
- 1;
3233 loop_end_rec
= length
;
3235 pindex
[i
] = rindex
= 0;
3236 play
[i
] = record
= bi
[i
] = false;
3237 looprec
= loopplay
[i
] = true;
3243 rampup
[i
] = rampdown
[i
] = false;
3244 rampup_len
[i
] = rampdown_len
[i
] = 0.;
3245 rampup_len_inv
[i
] = rampdown_len_inv
[i
] = 1.;
3252 // dump a sample into the buffer; retain existing sample, scaled by "coeff"
3253 inline void recordSamp(SAMPLE insample
)
3259 if(rindex
>= loop_end_rec
) rindex
= 0;
3260 tempsample
= coeff
* mdata
[rindex
] + insample
;
3261 //mdata[rindex] = coeff * mdata[rindex] + insample;
3264 if (rindex
< loop_end_rec
) {
3265 //mdata[rindex] = coeff * mdata[rindex] + insample;
3266 tempsample
= coeff
* mdata
[rindex
] + insample
;
3275 if(rindex
< rec_ramplen
) {
3276 tempsample
*= (rindex
* rec_ramplen_inv
);
3277 //fprintf(stderr, "ramping up %f\n", rindex * rec_ramplen_inv);
3278 } else if(rindex
> (loop_end_rec
- rec_ramplen
)) {
3279 tempsample
*= (loop_end_rec
- rindex
) * rec_ramplen_inv
;
3280 //fprintf(stderr, "ramping down %f\n", (loop_end_rec - rindex) * rec_ramplen_inv);
3282 mdata
[rindex
] = tempsample
;
3287 // grab a sample from the buffer, with linear interpolation (add prc's SINC interp later)
3288 // increment play index
3289 inline SAMPLE
getNextSamp(t_CKINT which
)
3292 if(loopplay
[which
]) {
3293 if(bi
[which
]) { // change direction if bidirectional mode
3294 if(pindex
[which
] >= loop_end
[which
] || pindex
[which
] < loop_start
[which
]) { //should be >= ?
3295 pindex
[which
] -= p_inc
[which
];
3296 p_inc
[which
] = -p_inc
[which
];
3299 if( loop_start
[which
] == loop_end
[which
] ) pindex
[which
] = loop_start
[which
]; //catch this condition to avoid infinite while loops
3301 while(pindex
[which
] >= loop_end
[which
]) pindex
[which
] = loop_start
[which
] + (pindex
[which
] - loop_end
[which
]); //again, >=?
3302 while(pindex
[which
] < loop_start
[which
]) pindex
[which
] = loop_end
[which
] - (loop_start
[which
] - pindex
[which
]);
3305 } else if(pindex
[which
] >= mdata_len
|| pindex
[which
] < 0) { //should be >=, no?
3307 //fprintf(stderr, "turning voice %d off!\n", which);
3312 t_CKINT whereTrunc
= (t_CKINT
) pindex
[which
];
3313 t_CKDOUBLE whereFrac
= pindex
[which
] - (t_CKDOUBLE
)whereTrunc
;
3314 t_CKINT whereNext
= whereTrunc
+ 1;
3316 if (loopplay
[which
]) {
3317 if((whereNext
) == loop_end
[which
]) {
3318 whereNext
= loop_start
[which
];
3321 if((whereTrunc
) == mdata_len
) {
3322 whereTrunc
= mdata_len
- 1;
3327 pindex
[which
] += p_inc
[which
];
3329 t_CKDOUBLE outsample
;
3330 outsample
= (t_CKDOUBLE
)mdata
[whereTrunc
] + (t_CKDOUBLE
)(mdata
[whereNext
] - mdata
[whereTrunc
]) * whereFrac
;
3334 outsample
*= rampctr
[which
]++ * rampup_len_inv
[which
]; //remove divide
3335 if(rampctr
[which
] >= rampup_len
[which
]) rampup
[which
] = false;
3337 else if(rampdown
[which
]) {
3338 outsample
*= (rampdown_len
[which
] - rampctr
[which
]++) * rampdown_len_inv
[which
];
3339 if(rampctr
[which
] >= rampdown_len
[which
]) {
3340 rampdown
[which
] = false;
3341 play
[which
] = false;
3345 outsample
*= voiceGain
[which
];
3347 return (SAMPLE
)outsample
;
3350 // grab a sample from the buffer, with linear interpolation (add prc's SINC interp later)
3351 // given a position within the buffer
3352 inline SAMPLE
getSamp(t_CKDOUBLE where
, t_CKINT which
)
3355 if(where
> loop_end
[which
]) where
= loop_end
[which
];
3356 if(where
< loop_start
[which
]) where
= loop_start
[which
];
3359 t_CKINT whereTrunc
= (t_CKINT
) where
;
3360 t_CKDOUBLE whereFrac
= where
- (t_CKDOUBLE
)whereTrunc
;
3361 t_CKINT whereNext
= whereTrunc
+ 1;
3363 if((whereNext
) == loop_end
[which
]) whereNext
= loop_start
[which
];
3365 t_CKDOUBLE outsample
;
3366 outsample
= (t_CKDOUBLE
)mdata
[whereTrunc
] + (t_CKDOUBLE
)(mdata
[whereNext
] - mdata
[whereTrunc
]) * whereFrac
;
3367 outsample
*= voiceGain
[which
];
3369 //add voiceGain ctl here; return (SAMPLE)vgain[which]*outsample;
3370 return (SAMPLE
)outsample
;
3374 inline void ramp_up(t_CKINT voicenum
, t_CKDUR uptime
)
3376 // fprintf(stderr, "ramping up voice %d", voicenum);
3378 rampup
[voicenum
] = true;
3379 play
[voicenum
] = true;
3380 rampup_len
[voicenum
] = (t_CKDOUBLE
)uptime
;
3381 if(rampup_len
[voicenum
] > 0.) rampup_len_inv
[voicenum
] = 1./rampup_len
[voicenum
];
3382 else rampup_len
[voicenum
] = 1.;
3384 // check to make sure we are not mid ramping down
3385 if(rampdown
[voicenum
]) {
3386 rampctr
[voicenum
] = rampup_len
[voicenum
] * (1. - rampctr
[voicenum
]/rampdown_len
[voicenum
]);
3387 rampdown
[voicenum
] = false;
3388 } else rampctr
[voicenum
] = 0;
3391 inline void ramp_down(t_CKINT voicenum
, t_CKDUR downtime
)
3393 rampdown
[voicenum
] = true;
3394 rampdown_len
[voicenum
] = (t_CKDOUBLE
)downtime
;
3395 if(rampdown_len
[voicenum
] > 0.) rampdown_len_inv
[voicenum
] = 1./rampdown_len
[voicenum
];
3396 else rampdown_len
[voicenum
] = 1.;
3398 // check to make sure we are not mid ramping up
3399 if(rampup
[voicenum
]) {
3400 rampctr
[voicenum
] = rampdown_len
[voicenum
] * (1. - rampctr
[voicenum
]/rampup_len
[voicenum
]);
3401 rampup
[voicenum
] = false;
3402 } else rampctr
[voicenum
] = 0;
3405 inline void set_rec_ramplen(t_CKDUR newlen
)
3407 rec_ramplen
= (t_CKDOUBLE
)newlen
;
3408 if(rec_ramplen
> 0.) rec_ramplen_inv
= 1./rec_ramplen
;
3409 else rec_ramplen_inv
= 1.;
3410 //fprintf ( stderr, "rec_ramplen = %f, inv = %f \n", rec_ramplen, rec_ramplen_inv );
3414 // may want to make multichannel version,
3415 // want to be able to do the following:
3417 // l.pan(voice, panval)
3418 //for simple stereo panning of a particular voice, and...
3419 // l.channelGain(voice, channel, gain)
3420 //to set the gain for a particular voice going to a particular channel; good for >2 voices (like 6 channels!)
3421 inline SAMPLE
tick_multi( SAMPLE in
)
3423 if(!mdata
) return (SAMPLE
) 0.;
3427 SAMPLE tempsample
= 0.;
3430 for (t_CKINT i
=0; i
<maxvoices
; i
++) {
3431 if(play
[i
]) tempsample
+= getNextSamp(i
);
3433 } else if(track
==1) {
3435 for (t_CKINT i
=0; i
<maxvoices
; i
++) {
3436 if(play
[i
]) tempsample
+= getSamp((t_CKDOUBLE
)in
* (loop_end
[i
] - loop_start
[i
]) + loop_start
[i
], i
);
3438 } else if(track
==2 && play
[0]) {
3439 if(in
<0.) in
= -in
; //only use voice 0 when tracking with durs.
3440 tempsample
= getSamp( (t_CKDOUBLE
)in
, 0 );
3446 inline void clear_buf()
3448 for (t_CKINT i
= 0; i
< mdata_len
; i
++)
3452 inline t_CKINT
get_free_voice()
3454 t_CKINT voicenumber
= 0;
3455 while(play
[voicenumber
] && voicenumber
< maxvoices
) {
3458 if(voicenumber
== maxvoices
) voicenumber
= -1;
3462 //stick sample in record buffer
3463 inline void pokeSample( SAMPLE insample
, t_CKINT index
) {
3465 if ( index
> mdata_len
|| index
< 0 ) {
3467 fprintf(stderr
, "LiSa: trying to put sample out of buffer range; ignoring");
3468 } else mdata
[index
] = insample
;
3472 //grab sample directly from record buffer, with linear interpolation
3473 inline SAMPLE
grabSample ( t_CKDOUBLE where
) {
3475 if ( where
> mdata_len
|| where
< 0 ) {
3477 fprintf(stderr
, "LiSa: trying to grab sample out of buffer range; ignoring");
3482 t_CKINT whereTrunc
= (t_CKINT
) where
;
3483 t_CKDOUBLE whereFrac
= where
- (t_CKDOUBLE
)whereTrunc
;
3484 t_CKINT whereNext
= whereTrunc
+ 1;
3486 if((whereNext
) == mdata_len
) whereNext
= 0;
3488 t_CKDOUBLE outsample
;
3489 outsample
= (t_CKDOUBLE
)mdata
[whereTrunc
] + (t_CKDOUBLE
)(mdata
[whereNext
] - mdata
[whereTrunc
]) * whereFrac
;
3491 //add voiceGain ctl here; return (SAMPLE)vgain[which]*outsample;
3492 return (SAMPLE
)outsample
;
3502 //++++++++++++++++++++++++++++++++++++++++
3505 //++++++++++++++++++++++++++++++++++++++++
3508 //++++++++++++++++++++++++++++++++++++++++
3513 //-----------------------------------------------------------------------------
3514 // name: LiSaMulti_ctor()
3515 // desc: CTOR function ...
3516 //-----------------------------------------------------------------------------
3517 CK_DLL_CTOR( LiSaMulti_ctor
)
3520 LiSaMulti_data
* f
= new LiSaMulti_data
;
3521 memset( f
, 0, sizeof(LiSaMulti_data
) );
3522 OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
) = (t_CKUINT
)f
;
3527 //-----------------------------------------------------------------------------
3528 // name: LiSaMulti_dtor()
3529 // desc: DTOR function ...
3530 //-----------------------------------------------------------------------------
3531 CK_DLL_DTOR( LiSaMulti_dtor
)
3534 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3538 OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
) = 0;
3542 //-----------------------------------------------------------------------------
3543 // name: LiSaMulti_tick()
3544 // desc: TICK function ...
3545 //-----------------------------------------------------------------------------
3546 CK_DLL_TICK( LiSaMulti_tick
)
3548 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3549 *out
= d
->tick_multi( in
);
3554 //-----------------------------------------------------------------------------
3555 // name: LiSaMulti_size()
3556 // desc: set size of buffer allocation
3557 //-----------------------------------------------------------------------------
3558 CK_DLL_CTRL( LiSaMulti_size
)
3560 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3561 t_CKDUR buflen
= GET_NEXT_DUR(ARGS
);
3562 if (buflen
> LiSa_MAXBUFSIZE
) {
3563 fprintf(stderr
, "buffer size request too large, resizing\n");
3564 buflen
= LiSa_MAXBUFSIZE
;
3566 d
->buffer_alloc((t_CKINT
)buflen
);
3568 RETURN
->v_dur
= (t_CKDUR
)buflen
;
3571 CK_DLL_CGET( LiSaMulti_cget_size
)
3573 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3575 RETURN
->v_dur
= (t_CKDUR
)d
->mdata_len
;
3579 //-----------------------------------------------------------------------------
3580 // name: LiSaMulti_start_record()
3581 // desc: CTRL function ...
3582 //-----------------------------------------------------------------------------
3583 CK_DLL_CTRL( LiSaMulti_start_record
)
3585 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3586 d
->record
= GET_NEXT_INT(ARGS
);
3588 RETURN
->v_int
= (t_CKINT
)d
->record
;
3592 //-----------------------------------------------------------------------------
3593 // name: LiSaMulti_start_play()
3594 // desc: CTRL function
3595 //-----------------------------------------------------------------------------
3596 CK_DLL_CTRL( LiSaMulti_start_play
)
3598 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3599 t_CKINT which
= GET_NEXT_INT(ARGS
);
3600 d
->play
[which
] = GET_NEXT_INT(ARGS
);
3601 //fprintf(stderr, "voice %d playing = %d\n", which, d->play[which]);
3603 //turn off ramping toggles
3604 d
->rampdown
[which
] = false;
3605 d
->rampup
[which
] = false;
3607 RETURN
->v_int
= (t_CKINT
)d
->play
[which
];
3611 //-----------------------------------------------------------------------------
3612 // name: LiSaMulti_start_play()
3613 // desc: CTRL function
3614 //-----------------------------------------------------------------------------
3615 CK_DLL_CTRL( LiSaMulti_start_play0
)
3618 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3619 d
->play
[0] = GET_NEXT_INT(ARGS
);
3620 //fprintf(stderr, "voice %d playing = %d\n", which, d->play[which]);
3622 //turn off ramping toggles
3623 d
->rampdown
[0] = false;
3624 d
->rampup
[0] = false;
3626 RETURN
->v_int
= (t_CKINT
)d
->play
[0];
3631 //-----------------------------------------------------------------------------
3632 // name: LiSaMulti_ctrl_rate()
3633 // desc: CTRL function
3634 //-----------------------------------------------------------------------------
3635 CK_DLL_CTRL( LiSaMulti_ctrl_rate
)
3637 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3638 t_CKINT which
= GET_NEXT_INT(ARGS
);
3639 d
->p_inc
[which
] = (t_CKDOUBLE
)GET_NEXT_FLOAT(ARGS
);
3640 //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]);
3642 RETURN
->v_float
= d
->p_inc
[which
];
3646 CK_DLL_CTRL( LiSaMulti_ctrl_rate0
)
3648 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3649 d
->p_inc
[0] = (t_CKDOUBLE
)GET_NEXT_FLOAT(ARGS
);
3650 //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]);
3652 RETURN
->v_float
= d
->p_inc
[0];
3655 //-----------------------------------------------------------------------------
3656 // name: LiSaMulti_cget_rate()
3657 // desc: CTRL function
3658 //-----------------------------------------------------------------------------
3659 CK_DLL_CTRL( LiSaMulti_cget_rate
)
3661 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3662 t_CKINT which
= GET_NEXT_INT(ARGS
);
3663 //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]);
3665 RETURN
->v_float
= d
->p_inc
[which
];
3669 CK_DLL_CTRL( LiSaMulti_cget_rate0
)
3671 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3672 //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]);
3674 RETURN
->v_float
= d
->p_inc
[0];
3677 //-----------------------------------------------------------------------------
3678 // name: LiSaMulti_ctrl_pindex()
3679 // desc: CTRL function
3680 //-----------------------------------------------------------------------------
3681 CK_DLL_CTRL( LiSaMulti_ctrl_pindex
)
3683 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3684 t_CKINT which
= GET_NEXT_INT(ARGS
);
3685 d
->pindex
[which
] = (t_CKDOUBLE
)GET_NEXT_DUR(ARGS
);
3687 RETURN
->v_dur
= (t_CKDUR
)d
->pindex
[which
];
3691 CK_DLL_CTRL( LiSaMulti_ctrl_pindex0
)
3693 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3694 d
->pindex
[0] = (t_CKDOUBLE
)GET_NEXT_DUR(ARGS
);
3696 RETURN
->v_dur
= (t_CKDUR
)d
->pindex
[0];
3700 //-----------------------------------------------------------------------------
3701 // name: LiSaMulti_cget_pindex()
3702 // desc: CGET function
3703 //-----------------------------------------------------------------------------
3704 CK_DLL_CGET( LiSaMulti_cget_pindex
)
3706 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3707 t_CKINT which
= GET_NEXT_INT(ARGS
);
3710 RETURN
->v_dur
= (t_CKDUR
)d
->pindex
[which
];
3714 CK_DLL_CGET( LiSaMulti_cget_pindex0
)
3716 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3719 RETURN
->v_dur
= (t_CKDUR
)d
->pindex
[0];
3723 //-----------------------------------------------------------------------------
3724 // name: LiSaMulti_ctrl_pindex()
3725 // desc: CTRL function
3726 //-----------------------------------------------------------------------------
3727 CK_DLL_CTRL( LiSaMulti_ctrl_rindex
)
3729 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3730 d
->rindex
= /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3732 RETURN
->v_dur
= (t_CKDUR
)d
->rindex
;
3736 //-----------------------------------------------------------------------------
3737 // name: LiSaMulti_cget_pindex()
3738 // desc: CGET function
3739 //-----------------------------------------------------------------------------
3740 CK_DLL_CGET( LiSaMulti_cget_rindex
)
3742 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3745 RETURN
->v_dur
= (t_CKDUR
)d
->rindex
;
3749 //-----------------------------------------------------------------------------
3750 // name: LiSaMulti_ctrl_lstart()
3751 // desc: CTRL function
3752 //-----------------------------------------------------------------------------
3753 CK_DLL_CTRL( LiSaMulti_ctrl_lstart
)
3755 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3756 t_CKINT which
= GET_NEXT_INT(ARGS
);
3757 d
->loop_start
[which
] = /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3759 if (d
->loop_start
[which
] < 0) d
->loop_start
[which
] = 0;
3761 RETURN
->v_dur
= (t_CKDUR
)d
->loop_start
[which
];
3765 CK_DLL_CTRL( LiSaMulti_ctrl_lstart0
)
3767 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3768 d
->loop_start
[0] = /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3770 if (d
->loop_start
[0] < 0) d
->loop_start
[0] = 0;
3772 RETURN
->v_dur
= (t_CKDUR
)d
->loop_start
[0];
3776 //-----------------------------------------------------------------------------
3777 // name: LiSaMulti_cget_lstart()
3778 // desc: CGET function
3779 //-----------------------------------------------------------------------------
3780 CK_DLL_CGET( LiSaMulti_cget_lstart
)
3782 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3784 t_CKINT which
= GET_NEXT_INT(ARGS
);
3786 RETURN
->v_dur
= (t_CKDUR
)d
->loop_start
[which
];
3790 CK_DLL_CGET( LiSaMulti_cget_lstart0
)
3792 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3795 RETURN
->v_dur
= (t_CKDUR
)d
->loop_start
[0];
3799 //-----------------------------------------------------------------------------
3800 // name: LiSaMulti_ctrl_lend()
3801 // desc: CTRL function
3802 //-----------------------------------------------------------------------------
3803 CK_DLL_CTRL( LiSaMulti_ctrl_lend
)
3805 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3806 t_CKINT which
= GET_NEXT_INT(ARGS
);
3807 d
->loop_end
[which
] = /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3809 //check to make sure loop_end is not too large
3810 if (d
->loop_end
[which
] >= d
->mdata_len
) d
->loop_end
[which
] = d
->mdata_len
- 1;
3812 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end
[which
];
3816 CK_DLL_CTRL( LiSaMulti_ctrl_lend0
)
3818 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3819 d
->loop_end
[0] = /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3821 //check to make sure loop_end is not too large
3822 if (d
->loop_end
[0] >= d
->mdata_len
) d
->loop_end
[0] = d
->mdata_len
- 1;
3824 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end
[0];
3828 //-----------------------------------------------------------------------------
3829 // name: LiSaMulti_cget_lend()
3830 // desc: CGET function
3831 //-----------------------------------------------------------------------------
3832 CK_DLL_CGET( LiSaMulti_cget_lend
)
3834 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3835 t_CKINT which
= GET_NEXT_INT(ARGS
);
3838 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end
[which
];
3842 CK_DLL_CGET( LiSaMulti_cget_lend0
)
3844 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3847 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end
[0];
3851 //-----------------------------------------------------------------------------
3852 // name: LiSaMulti_ctrl_loop()
3853 // desc: CTRL function
3854 //-----------------------------------------------------------------------------
3855 CK_DLL_CTRL( LiSaMulti_ctrl_loop
)
3857 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3858 t_CKINT which
= GET_NEXT_INT(ARGS
);
3859 d
->loopplay
[which
] = (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3863 CK_DLL_CTRL( LiSaMulti_ctrl_loop0
)
3865 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3866 d
->loopplay
[0] = (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3868 RETURN
->v_int
= (t_CKINT
)d
->loopplay
[0];
3872 //-----------------------------------------------------------------------------
3873 // name: LiSaMulti_cget_loop()
3874 // desc: CGET function
3875 //-----------------------------------------------------------------------------
3876 CK_DLL_CGET( LiSaMulti_cget_loop
)
3878 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3879 t_CKINT which
= GET_NEXT_INT(ARGS
);
3882 RETURN
->v_int
= (t_CKINT
)d
->loopplay
[which
];
3886 CK_DLL_CGET( LiSaMulti_cget_loop0
)
3888 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3891 RETURN
->v_int
= (t_CKINT
)d
->loopplay
[0];
3895 //-----------------------------------------------------------------------------
3896 // name: LiSaMulti_ctrl_bi()
3897 // desc: CTRL function
3898 //-----------------------------------------------------------------------------
3899 CK_DLL_CTRL( LiSaMulti_ctrl_bi
)
3901 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3902 t_CKINT which
= GET_NEXT_INT(ARGS
);
3903 d
->bi
[which
] = (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3905 RETURN
->v_int
= (t_CKINT
)d
->bi
[which
];
3909 CK_DLL_CTRL( LiSaMulti_ctrl_bi0
)
3911 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3912 d
->bi
[0] = (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3914 RETURN
->v_int
= (t_CKINT
)d
->bi
[0];
3918 //-----------------------------------------------------------------------------
3919 // name: LiSaMulti_cget_bi()
3920 // desc: CGET function
3921 //-----------------------------------------------------------------------------
3922 CK_DLL_CGET( LiSaMulti_cget_bi
)
3924 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3925 t_CKINT which
= GET_NEXT_INT(ARGS
);
3928 RETURN
->v_int
= (t_CKINT
)d
->bi
[which
];
3932 CK_DLL_CGET( LiSaMulti_cget_bi0
)
3934 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3937 RETURN
->v_int
= (t_CKINT
)d
->bi
[0];
3941 //-----------------------------------------------------------------------------
3942 // name: LiSaMulti_ctrl_loop_end_rec()
3943 // desc: CTRL function
3944 //-----------------------------------------------------------------------------
3945 CK_DLL_CTRL( LiSaMulti_ctrl_loop_end_rec
)
3947 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3948 d
->loop_end_rec
= /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3950 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end_rec
;
3954 //-----------------------------------------------------------------------------
3955 // name: LiSaMulti_cget_loop_end_rec()
3956 // desc: CGET function
3957 //-----------------------------------------------------------------------------
3958 CK_DLL_CGET( LiSaMulti_cget_loop_end_rec
)
3960 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3963 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end_rec
;
3967 //-----------------------------------------------------------------------------
3968 // name: LiSaMulti_ctrl_loop_rec()
3969 // desc: CTRL function
3970 //-----------------------------------------------------------------------------
3971 CK_DLL_CTRL( LiSaMulti_ctrl_loop_rec
)
3973 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3974 d
->looprec
= (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3976 RETURN
->v_int
= (t_CKINT
)d
->looprec
;
3980 //-----------------------------------------------------------------------------
3981 // name: LiSaMulti_cget_loop_rec()
3982 // desc: CGET function
3983 //-----------------------------------------------------------------------------
3984 CK_DLL_CGET( LiSaMulti_cget_loop_rec
)
3986 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3989 RETURN
->v_int
= (t_CKINT
)d
->looprec
;
3992 //-----------------------------------------------------------------------------
3993 // name: LiSaMulti_ctrl_sample(); put a sample directly into record buffer
3994 // desc: CTRL function
3995 //-----------------------------------------------------------------------------
3996 CK_DLL_CTRL( LiSaMulti_ctrl_sample
)
3998 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3999 SAMPLE sample_in
= (SAMPLE
)GET_NEXT_FLOAT(ARGS
);
4000 int index_in
= (t_CKINT
)GET_NEXT_DUR(ARGS
);
4002 d
->pokeSample( sample_in
, index_in
);
4004 RETURN
->v_float
= (t_CKFLOAT
)sample_in
; //pass input through
4007 //-----------------------------------------------------------------------------
4008 // name: LiSaMulti_cget_sample(); grab a sample from the record buffer
4009 // desc: CGET function
4010 //-----------------------------------------------------------------------------
4011 CK_DLL_CGET( LiSaMulti_cget_sample
)
4013 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4014 double index_in
= (t_CKDOUBLE
)GET_NEXT_DUR(ARGS
);
4016 RETURN
->v_float
= (t_CKFLOAT
)d
->grabSample( index_in
); //change this to getSamp for interpolation
4020 //-----------------------------------------------------------------------------
4021 // name: LiSaMulti_ctrl_voicegain()
4022 // desc: CTRL function
4023 //-----------------------------------------------------------------------------
4024 CK_DLL_CTRL( LiSaMulti_ctrl_voicegain
)
4026 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4027 t_CKINT which
= GET_NEXT_INT(ARGS
);
4028 d
->voiceGain
[which
] = (t_CKDOUBLE
)GET_NEXT_FLOAT(ARGS
);
4030 RETURN
->v_float
= (t_CKFLOAT
)d
->coeff
;
4034 //-----------------------------------------------------------------------------
4035 // name: LiSaMulti_cget_voicegain()
4036 // desc: CGET function
4037 //-----------------------------------------------------------------------------
4038 CK_DLL_CGET( LiSaMulti_cget_voicegain
)
4040 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4041 t_CKINT which
= GET_NEXT_INT(ARGS
);
4044 RETURN
->v_float
= (t_CKFLOAT
)d
->voiceGain
[which
];
4048 //-----------------------------------------------------------------------------
4049 // name: LiSaMulti_ctrl_coeff()
4050 // desc: CTRL function
4051 //-----------------------------------------------------------------------------
4052 CK_DLL_CTRL( LiSaMulti_ctrl_coeff
)
4054 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4055 d
->coeff
= (t_CKDOUBLE
)GET_NEXT_FLOAT(ARGS
);
4057 RETURN
->v_float
= (t_CKFLOAT
)d
->coeff
;
4060 //-----------------------------------------------------------------------------
4061 // name: LiSaMulti_cget_coeff()
4062 // desc: CGET function
4063 //-----------------------------------------------------------------------------
4064 CK_DLL_CGET( LiSaMulti_cget_coeff
)
4066 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4069 RETURN
->v_float
= (t_CKFLOAT
)d
->coeff
;
4073 //-----------------------------------------------------------------------------
4074 // name: LiSaMulti_ctrl_clear()
4075 // desc: CTRL function
4076 //-----------------------------------------------------------------------------
4077 CK_DLL_CTRL( LiSaMulti_ctrl_clear
)
4079 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4085 //-----------------------------------------------------------------------------
4086 // name: LiSaMulti_cget_voice()
4087 // desc: CGET function
4088 //-----------------------------------------------------------------------------
4089 CK_DLL_CGET( LiSaMulti_cget_voice
)
4091 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4094 RETURN
->v_int
= (t_CKINT
)d
->get_free_voice();
4099 //-----------------------------------------------------------------------------
4100 // name: LiSaMulti_ctrl_rampup()
4101 // desc: CTRL function
4102 //-----------------------------------------------------------------------------
4103 CK_DLL_CTRL( LiSaMulti_ctrl_rampup
)
4105 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4106 t_CKINT voice
= GET_NEXT_INT(ARGS
);
4107 t_CKDUR len
= GET_NEXT_DUR(ARGS
);
4109 d
->ramp_up(voice
, len
);
4111 RETURN
->v_dur
= (t_CKDUR
)len
;
4115 CK_DLL_CTRL( LiSaMulti_ctrl_rampup0
)
4117 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4118 t_CKDUR len
= GET_NEXT_DUR(ARGS
);
4122 RETURN
->v_dur
= (t_CKDUR
)len
;
4126 //-----------------------------------------------------------------------------
4127 // name: LiSaMulti_ctrl_rampdown()
4128 // desc: CTRL function
4129 //-----------------------------------------------------------------------------
4130 CK_DLL_CTRL( LiSaMulti_ctrl_rampdown
)
4132 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4133 t_CKINT voice
= GET_NEXT_INT(ARGS
);
4134 t_CKDUR len
= GET_NEXT_DUR(ARGS
);
4136 d
->ramp_down(voice
, len
);
4138 RETURN
->v_dur
= (t_CKDUR
)len
;
4142 CK_DLL_CTRL( LiSaMulti_ctrl_rampdown0
)
4144 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4145 t_CKDUR len
= GET_NEXT_DUR(ARGS
);
4147 d
->ramp_down(0, len
);
4149 RETURN
->v_dur
= (t_CKDUR
)len
;
4153 //-----------------------------------------------------------------------------
4154 // name: LiSaMulti_ctrl_rec_ramplen()
4155 // desc: CTRL function
4156 //-----------------------------------------------------------------------------
4157 CK_DLL_CTRL( LiSaMulti_ctrl_rec_ramplen
)
4159 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4160 t_CKDUR newramplen
= GET_NEXT_DUR(ARGS
);
4161 d
->set_rec_ramplen(newramplen
);
4163 RETURN
->v_dur
= (t_CKDUR
)newramplen
;
4167 //-----------------------------------------------------------------------------
4168 // name: LiSaMulti_ctrl_maxvoices()
4169 // desc: CTRL function
4170 //-----------------------------------------------------------------------------
4171 CK_DLL_CTRL( LiSaMulti_ctrl_maxvoices
)
4173 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4174 d
->maxvoices
= GET_NEXT_INT(ARGS
);
4175 if( d
->maxvoices
> LiSa_MAXVOICES
) {
4176 d
->maxvoices
= LiSa_MAXVOICES
;
4177 fprintf(stderr
, "LiSa: MAXVOICES limited to %d.\n", LiSa_MAXVOICES
);
4179 RETURN
->v_int
= d
->maxvoices
;
4183 //-----------------------------------------------------------------------------
4184 // name: LiSaMulti_cget_maxvoices()
4185 // desc: CGET function
4186 //-----------------------------------------------------------------------------
4187 CK_DLL_CGET( LiSaMulti_cget_maxvoices
)
4189 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4192 RETURN
->v_int
= d
->maxvoices
;
4196 //-----------------------------------------------------------------------------
4197 // name: LiSaMulti_cget_samp()
4198 // desc: CGET function
4199 //-----------------------------------------------------------------------------
4200 CK_DLL_CGET( LiSaMulti_cget_value
)
4202 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4203 t_CKINT voice
= GET_NEXT_INT(ARGS
);
4204 t_CKDOUBLE where
= (t_CKDOUBLE
) GET_NEXT_DUR(ARGS
);
4207 RETURN
->v_dur
= (t_CKDUR
)d
->getSamp(where
, voice
);
4211 CK_DLL_CGET( LiSaMulti_cget_value0
)
4213 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4215 t_CKDOUBLE where
= (t_CKDOUBLE
) GET_NEXT_DUR(ARGS
);
4217 RETURN
->v_dur
= (t_CKDUR
)d
->getSamp(where
, 0);
4221 //-----------------------------------------------------------------------------
4222 // name: LiSaMulti_ctrl_track()
4223 // desc: CTRL function
4224 //-----------------------------------------------------------------------------
4225 CK_DLL_CTRL( LiSaMulti_ctrl_track
)
4227 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4228 d
->track
= (t_CKINT
)GET_NEXT_INT(ARGS
);
4230 RETURN
->v_int
= d
->track
;
4234 //-----------------------------------------------------------------------------
4235 // name: LiSaMulti_cget_sync()
4236 // desc: CGET function
4237 //-----------------------------------------------------------------------------
4238 CK_DLL_CGET( LiSaMulti_cget_track
)
4240 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4243 RETURN
->v_int
= d
->track
;
4247 //-----------------------------------------------------------------------------
4248 // name: LiSaMulti_pmsg()
4249 // desc: PMSG function ...
4250 //-----------------------------------------------------------------------------
4251 CK_DLL_PMSG(LiSaMulti_pmsg
)