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 zerox_offset_data
= 0;
72 static t_CKUINT delayp_offset_data
= 0;
73 static t_CKUINT sndbuf_offset_data
= 0;
74 static t_CKUINT dyno_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
514 //! sound buffer ( now interpolating )
515 //! reads from a variety of file formats
516 //! see \example sndbuf.ck
517 //QUERY->ugen_add( QUERY, "sndbuf", NULL );
519 //QUERY->ugen_func( QUERY, sndbuf_ctor, sndbuf_dtor, sndbuf_tick, NULL );
521 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_read, NULL, "string", "read" ); //! loads file for reading
522 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_write, NULL, "string", "write" ); //! loads a file for writing ( or not )
523 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_pos, sndbuf_cget_pos, "int", "pos" ); //! set position ( 0 < p < .samples )
524 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_loop, sndbuf_cget_loop, "int", "loop" ); //! toggle looping
525 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_interp, sndbuf_cget_interp, "int", "interp" ); //! set interpolation ( 0=drop, 1=linear, 2=sinc )
526 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_rate, sndbuf_cget_rate, "float", "rate" ); //! playback rate ( relative to file's natural speed )
527 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_rate, sndbuf_cget_rate, "float", "play" ); //! play (same as rate)
528 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_freq, sndbuf_cget_freq, "float", "freq" ); //! playback rate ( file loops / second )
529 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_phase, sndbuf_cget_phase, "float", "phase" ); //! set phase position ( 0-1 )
530 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_channel, sndbuf_cget_channel, "int", "channel" ); //! select channel ( 0 < p < .channels )
531 //QUERY->ugen_ctrl( QUERY, sndbuf_ctrl_phase_offset, sndbuf_cget_phase, "float", "phase_offset" ); //! set a phase offset
532 //QUERY->ugen_ctrl( QUERY, NULL, sndbuf_cget_samples, "int", "samples" ); //! fetch number of samples
533 //QUERY->ugen_ctrl( QUERY, NULL, sndbuf_cget_length, "dur", "length" ); //! fetch length
534 //QUERY->ugen_ctrl( QUERY, NULL, sndbuf_cget_channels, "int", "channels" ); //! fetch number of channels
536 //---------------------------------------------------------------------
537 // init as base class: sndbuf
538 //---------------------------------------------------------------------
539 if( !type_engine_import_ugen_begin( env
, "SndBuf", "UGen", env
->global(),
540 sndbuf_ctor
, sndbuf_dtor
,
541 sndbuf_tick
, NULL
) )
544 // add member variable
545 sndbuf_offset_data
= type_engine_import_mvar( env
, "int", "@sndbuf_data", FALSE
);
546 if( sndbuf_offset_data
== CK_INVALID_OFFSET
) goto error
;
549 func
= make_new_mfun( "string", "read", sndbuf_ctrl_read
);
550 func
->add_arg( "string", "read" );
551 if( !type_engine_import_mfun( env
, func
) ) goto error
;
552 // add cget: read // area
553 //func = make_new_mfun( "string", "read", sndbuf_cget_read );
554 //if( !type_engine_import_mfun( env, func ) ) goto error;
557 func
= make_new_mfun( "string", "write", sndbuf_ctrl_write
);
558 func
->add_arg( "string", "read" );
559 if( !type_engine_import_mfun( env
, func
) ) goto error
;
561 //func = make_new_mfun( "string", "write", sndbuf_cget_write );
562 //if( !type_engine_import_mfun( env, func ) ) goto error;
565 func
= make_new_mfun( "int", "pos", sndbuf_ctrl_pos
);
566 func
->add_arg( "int", "pos" );
567 if( !type_engine_import_mfun( env
, func
) ) goto error
;
569 func
= make_new_mfun( "int", "pos", sndbuf_cget_pos
);
570 if( !type_engine_import_mfun( env
, func
) ) goto error
;
573 func
= make_new_mfun( "int", "loop", sndbuf_ctrl_loop
);
574 func
->add_arg( "int", "loop" );
575 if( !type_engine_import_mfun( env
, func
) ) goto error
;
577 func
= make_new_mfun( "int", "loop", sndbuf_cget_loop
);
578 if( !type_engine_import_mfun( env
, func
) ) goto error
;
581 func
= make_new_mfun( "int", "interp", sndbuf_ctrl_interp
);
582 func
->add_arg( "int", "interp" );
583 if( !type_engine_import_mfun( env
, func
) ) goto error
;
585 func
= make_new_mfun( "int", "interp", sndbuf_cget_interp
);
586 if( !type_engine_import_mfun( env
, func
) ) goto error
;
589 func
= make_new_mfun( "float", "rate", sndbuf_ctrl_rate
);
590 func
->add_arg( "float", "rate" );
591 if( !type_engine_import_mfun( env
, func
) ) goto error
;
593 func
= make_new_mfun( "float", "rate", sndbuf_cget_rate
);
594 if( !type_engine_import_mfun( env
, func
) ) goto error
;
597 func
= make_new_mfun( "float", "play", sndbuf_ctrl_rate
);
598 func
->add_arg( "float", "play" );
599 if( !type_engine_import_mfun( env
, func
) ) goto error
;
600 // add cget: play // good
601 func
= make_new_mfun( "float", "play", sndbuf_cget_rate
);
602 if( !type_engine_import_mfun( env
, func
) ) goto error
;
605 func
= make_new_mfun( "float", "freq", sndbuf_ctrl_freq
);
606 func
->add_arg( "float", "freq" );
607 if( !type_engine_import_mfun( env
, func
) ) goto error
;
609 func
= make_new_mfun( "float", "freq", sndbuf_cget_freq
);
610 if( !type_engine_import_mfun( env
, func
) ) goto error
;
613 func
= make_new_mfun( "float", "phase", sndbuf_ctrl_phase
);
614 func
->add_arg( "float", "phase" );
615 if( !type_engine_import_mfun( env
, func
) ) goto error
;
617 func
= make_new_mfun( "float", "phase", sndbuf_cget_phase
);
618 if( !type_engine_import_mfun( env
, func
) ) goto error
;
621 func
= make_new_mfun( "int", "channel", sndbuf_ctrl_channel
);
622 func
->add_arg( "int", "channel" );
623 if( !type_engine_import_mfun( env
, func
) ) goto error
;
625 func
= make_new_mfun( "int", "channel", sndbuf_cget_channel
);
626 if( !type_engine_import_mfun( env
, func
) ) goto error
;
628 // add ctrl: phase_offset
629 func
= make_new_mfun( "float", "phaseOffset", sndbuf_ctrl_phase_offset
);
630 func
->add_arg( "float", "value" );
631 if( !type_engine_import_mfun( env
, func
) ) goto error
;
632 // add cget: phase_offset
633 // func = make_new_mfun( "float", "phaseOffset", sndbuf_cget_phase_offset );
634 // if( !type_engine_import_mfun( env, func ) ) goto error;
637 func
= make_new_mfun( "int", "chunks", sndbuf_ctrl_chunks
);
638 func
->add_arg( "int", "frames" );
639 if( !type_engine_import_mfun( env
, func
) ) goto error
;
641 func
= make_new_mfun( "int", "chunks", sndbuf_cget_chunks
);
642 if( !type_engine_import_mfun( env
, func
) ) goto error
;
645 func
= make_new_mfun( "int", "samples", sndbuf_cget_samples
);
646 if( !type_engine_import_mfun( env
, func
) ) goto error
;
649 func
= make_new_mfun( "dur", "length", sndbuf_cget_length
);
650 if( !type_engine_import_mfun( env
, func
) ) goto error
;
652 // add cget: channels
653 func
= make_new_mfun( "int", "channels", sndbuf_cget_channels
);
654 if( !type_engine_import_mfun( env
, func
) ) goto error
;
657 func
= make_new_mfun( "float", "valueAt", sndbuf_cget_valueAt
);
658 func
->add_arg( "int", "pos" );
659 if( !type_engine_import_mfun( env
, func
) ) goto error
;
662 if( !type_engine_import_class_end( env
) )
665 //---------------------------------------------------------------------
666 // init as base class: Dyno
667 //---------------------------------------------------------------------
668 if( !type_engine_import_ugen_begin( env
, "Dyno", "UGen", env
->global(),
669 dyno_ctor
, dyno_dtor
, dyno_tick
, NULL
) )
672 // add member variable
673 dyno_offset_data
= type_engine_import_mvar( env
, "int", "@dyno_data", FALSE
);
674 if( dyno_offset_data
== CK_INVALID_OFFSET
) goto error
;
677 func
= make_new_mfun( "void", "limit", dyno_ctrl_limit
);
678 //func->add_arg( "string", "mode" );
679 if( !type_engine_import_mfun( env
, func
) ) goto error
;
681 // add ctrl: compress
682 func
= make_new_mfun( "void", "compress", dyno_ctrl_compress
);
683 //func->add_arg( "string", "mode" );
684 if( !type_engine_import_mfun( env
, func
) ) goto error
;
687 func
= make_new_mfun( "void", "gate", dyno_ctrl_gate
);
688 //func->add_arg( "string", "mode" );
689 if( !type_engine_import_mfun( env
, func
) ) goto error
;
692 func
= make_new_mfun( "void", "expand", dyno_ctrl_expand
);
693 //func->add_arg( "string", "mode" );
694 if( !type_engine_import_mfun( env
, func
) ) goto error
;
697 func
= make_new_mfun( "void", "duck", dyno_ctrl_duck
);
698 //func->add_arg( "string", "mode" );
699 if( !type_engine_import_mfun( env
, func
) ) goto error
;
702 func
= make_new_mfun( "float", "thresh", dyno_ctrl_thresh
);
703 func
->add_arg( "float", "thresh" );
704 if( !type_engine_import_mfun( env
, func
) ) goto error
;
707 func
= make_new_mfun( "float", "thresh", dyno_cget_thresh
);
708 if( !type_engine_import_mfun( env
, func
) ) goto error
;
710 //add ctrl: attackTime
711 func
= make_new_mfun( "dur", "attackTime", dyno_ctrl_attackTime
);
712 func
->add_arg( "dur", "aTime" );
713 if( !type_engine_import_mfun( env
, func
) ) goto error
;
715 //add cget: attackTime
716 func
= make_new_mfun( "dur", "attackTime", dyno_ctrl_attackTime
);
717 if( !type_engine_import_mfun( env
, func
) ) goto error
;
719 //add ctrl: releaseTime
720 func
= make_new_mfun( "dur", "releaseTime", dyno_ctrl_releaseTime
);
721 func
->add_arg( "dur", "rTime" );
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 if( !type_engine_import_mfun( env
, func
) ) goto error
;
729 func
= make_new_mfun( "float", "ratio", dyno_ctrl_ratio
);
730 func
->add_arg( "float", "ratio" );
731 if( !type_engine_import_mfun( env
, func
) ) goto error
;
734 func
= make_new_mfun( "float", "ratio", dyno_cget_ratio
);
735 if( !type_engine_import_mfun( env
, func
) ) goto error
;
737 //add ctrl: slopeBelow
738 func
= make_new_mfun( "float", "slopeBelow", dyno_ctrl_slopeBelow
);
739 func
->add_arg( "float", "slopeBelow" );
740 if( !type_engine_import_mfun( env
, func
) ) goto error
;
742 //add cget: slopeBelow
743 func
= make_new_mfun( "float", "slopeBelow", dyno_cget_slopeBelow
);
744 if( !type_engine_import_mfun( env
, func
) ) goto error
;
746 //add ctrl: slopeAbove
747 func
= make_new_mfun( "float", "slopeAbove", dyno_ctrl_slopeAbove
);
748 func
->add_arg( "float", "slopeAbove" );
749 if( !type_engine_import_mfun( env
, func
) ) goto error
;
751 //add cget: slopeAbove
752 func
= make_new_mfun( "float", "slopeAbove", dyno_cget_slopeAbove
);
753 if( !type_engine_import_mfun( env
, func
) ) goto error
;
755 //add ctrl: sideInput
756 func
= make_new_mfun( "float", "sideInput", dyno_ctrl_sideInput
);
757 func
->add_arg( "float", "sideInput" );
758 if( !type_engine_import_mfun( env
, func
) ) goto error
;
760 //add cget: sideInput
761 func
= make_new_mfun( "float", "sideInput", dyno_cget_sideInput
);
762 if( !type_engine_import_mfun( env
, func
) ) goto error
;
764 //add ctrl: externalSideInput
765 func
= make_new_mfun( "int", "externalSideInput", dyno_ctrl_externalSideInput
);
766 func
->add_arg( "int", "externalSideInput" );
767 if( !type_engine_import_mfun( env
, func
) ) goto error
;
769 //add cget: externalSideInput
770 func
= make_new_mfun( "int", "externalSideInput", dyno_cget_externalSideInput
);
771 if( !type_engine_import_mfun( env
, func
) ) goto error
;
774 if( !type_engine_import_class_end( env
) )
778 if( !lisa_query( QUERY
) )
785 // end the class import
786 type_engine_import_class_end( env
);
794 // LiSa (live sampling data offset)
795 static t_CKUINT LiSaBasic_offset_data
= 0;
796 static t_CKUINT LiSaMulti_offset_data
= 0;
798 //-----------------------------------------------------------------------------
799 // name: lisa_query()
801 //-----------------------------------------------------------------------------
802 DLL_QUERY
lisa_query( Chuck_DL_Query
* QUERY
)
804 Chuck_Env
* env
= Chuck_Env::instance();
805 Chuck_DL_Func
* func
= NULL
;
807 //---------------------------------------------------------------------
808 // init class: LiSa; overloaded class for both LiSaBasic and LiSaMulti
809 // - probably don't need the others anymore....
810 // author: Dan Trueman (dan /at/ music.princeton.edu)
811 //---------------------------------------------------------------------
812 if( !type_engine_import_ugen_begin( env
, "LiSa", "UGen", env
->global(),
813 LiSaMulti_ctor
, LiSaMulti_dtor
,
814 LiSaMulti_tick
, LiSaMulti_pmsg
) )
817 // set/get buffer size
818 func
= make_new_mfun( "dur", "duration", LiSaMulti_size
);
819 func
->add_arg( "dur", "val" );
820 if( !type_engine_import_mfun( env
, func
) ) goto error
;
821 func
= make_new_mfun( "dur", "duration", LiSaMulti_cget_size
);
822 if( !type_engine_import_mfun( env
, func
) ) goto error
;
824 // start/stop recording
825 func
= make_new_mfun( "int", "record", LiSaMulti_start_record
);
826 func
->add_arg( "int", "toggle" );
827 if( !type_engine_import_mfun( env
, func
) ) goto error
;
829 // start/stop playing
830 func
= make_new_mfun( "int", "play", LiSaMulti_start_play
);
831 func
->add_arg( "int", "voice" );
832 func
->add_arg( "int", "toggle" );
833 if( !type_engine_import_mfun( env
, func
) ) goto error
;
834 func
= make_new_mfun( "int", "play", LiSaMulti_start_play0
);
835 func
->add_arg( "int", "toggle" );
836 if( !type_engine_import_mfun( env
, func
) ) goto error
;
838 // set/get playback rate
839 func
= make_new_mfun( "float", "rate", LiSaMulti_ctrl_rate
);
840 func
->add_arg( "int", "voice" );
841 func
->add_arg( "float", "val" );
842 if( !type_engine_import_mfun( env
, func
) ) goto error
;
843 func
= make_new_mfun( "float", "rate", LiSaMulti_cget_rate
);
844 func
->add_arg( "int", "voice" );
845 if( !type_engine_import_mfun( env
, func
) ) goto error
;
846 func
= make_new_mfun( "float", "rate", LiSaMulti_ctrl_rate0
);
847 func
->add_arg( "float", "val" );
848 if( !type_engine_import_mfun( env
, func
) ) goto error
;
849 func
= make_new_mfun( "float", "rate", LiSaMulti_cget_rate0
);
850 if( !type_engine_import_mfun( env
, func
) ) goto error
;
853 func
= make_new_mfun( "dur", "playPos", LiSaMulti_ctrl_pindex
);
854 func
->add_arg( "int", "voice" );
855 func
->add_arg( "dur", "val" );
856 if( !type_engine_import_mfun( env
, func
) ) goto error
;
857 func
= make_new_mfun( "dur", "playPos", LiSaMulti_cget_pindex
);
858 func
->add_arg( "int", "voice" );
859 if( !type_engine_import_mfun( env
, func
) ) goto error
;
860 func
= make_new_mfun( "dur", "playPos", LiSaMulti_ctrl_pindex0
);
861 func
->add_arg( "dur", "val" );
862 if( !type_engine_import_mfun( env
, func
) ) goto error
;
863 func
= make_new_mfun( "dur", "playPos", LiSaMulti_cget_pindex0
);
864 if( !type_engine_import_mfun( env
, func
) ) goto error
;
867 func
= make_new_mfun( "dur", "recPos", LiSaMulti_ctrl_rindex
);
868 func
->add_arg( "dur", "val" );
869 if( !type_engine_import_mfun( env
, func
) ) goto error
;
870 func
= make_new_mfun( "dur", "recPos", LiSaMulti_cget_rindex
);
871 if( !type_engine_import_mfun( env
, func
) ) goto error
;
873 // loopstart position
874 func
= make_new_mfun( "dur", "loopStart", LiSaMulti_ctrl_lstart
);
875 func
->add_arg( "int", "voice" );
876 func
->add_arg( "dur", "val" );
877 if( !type_engine_import_mfun( env
, func
) ) goto error
;
878 func
= make_new_mfun( "dur", "loopStart", LiSaMulti_cget_lstart
);
879 func
->add_arg( "int", "voice" );
880 if( !type_engine_import_mfun( env
, func
) ) goto error
;
881 func
= make_new_mfun( "dur", "loopStart", LiSaMulti_ctrl_lstart0
);
882 func
->add_arg( "dur", "val" );
883 if( !type_engine_import_mfun( env
, func
) ) goto error
;
884 func
= make_new_mfun( "dur", "loopStart", LiSaMulti_cget_lstart0
);
885 if( !type_engine_import_mfun( env
, func
) ) goto error
;
888 func
= make_new_mfun( "dur", "loopEnd", LiSaMulti_ctrl_lend
);
889 func
->add_arg( "int", "voice" );
890 func
->add_arg( "dur", "val" );
891 if( !type_engine_import_mfun( env
, func
) ) goto error
;
892 func
= make_new_mfun( "dur", "loopEnd", LiSaMulti_cget_lend
);
893 func
->add_arg( "int", "voice" );
894 if( !type_engine_import_mfun( env
, func
) ) goto error
;
895 func
= make_new_mfun( "dur", "loopEnd", LiSaMulti_ctrl_lend0
);
896 func
->add_arg( "dur", "val" );
897 if( !type_engine_import_mfun( env
, func
) ) goto error
;
898 func
= make_new_mfun( "dur", "loopEnd", LiSaMulti_cget_lend0
);
899 if( !type_engine_import_mfun( env
, func
) ) goto error
;
902 func
= make_new_mfun( "int", "loop", LiSaMulti_ctrl_loop
);
903 func
->add_arg( "int", "voice" );
904 func
->add_arg( "int", "val" );
905 if( !type_engine_import_mfun( env
, func
) ) goto error
;
906 func
= make_new_mfun( "int", "loop", LiSaMulti_cget_loop
);
907 func
->add_arg( "int", "voice" );
908 if( !type_engine_import_mfun( env
, func
) ) goto error
;
909 func
= make_new_mfun( "int", "loop", LiSaMulti_ctrl_loop0
);
910 func
->add_arg( "int", "val" );
911 if( !type_engine_import_mfun( env
, func
) ) goto error
;
912 func
= make_new_mfun( "int", "loop", LiSaMulti_cget_loop0
);
913 if( !type_engine_import_mfun( env
, func
) ) goto error
;
915 // bidirectional looping
916 func
= make_new_mfun( "int", "bi", LiSaMulti_ctrl_bi
);
917 func
->add_arg( "int", "voice" );
918 func
->add_arg( "int", "val" );
919 if( !type_engine_import_mfun( env
, func
) ) goto error
;
920 func
= make_new_mfun( "int", "bi", LiSaMulti_cget_bi
);
921 func
->add_arg( "int", "voice" );
922 if( !type_engine_import_mfun( env
, func
) ) goto error
;
923 func
= make_new_mfun( "int", "bi", LiSaMulti_ctrl_bi0
);
924 func
->add_arg( "int", "val" );
925 if( !type_engine_import_mfun( env
, func
) ) goto error
;
926 func
= make_new_mfun( "int", "bi", LiSaMulti_cget_bi0
);
927 if( !type_engine_import_mfun( env
, func
) ) goto error
;
929 // loopend_rec position
930 func
= make_new_mfun( "dur", "loopEndRec", LiSaMulti_ctrl_loop_end_rec
);
931 func
->add_arg( "dur", "val" );
932 if( !type_engine_import_mfun( env
, func
) ) goto error
;
933 func
= make_new_mfun( "dur", "loopEndRec", LiSaMulti_cget_loop_end_rec
);
934 if( !type_engine_import_mfun( env
, func
) ) goto error
;
936 // loop_rec toggle set; for turning on/off loop recording
937 func
= make_new_mfun( "int", "loopRec", LiSaMulti_ctrl_loop_rec
);
938 func
->add_arg( "int", "val" );
939 if( !type_engine_import_mfun( env
, func
) ) goto error
;
940 func
= make_new_mfun( "int", "loopRec", LiSaMulti_cget_loop_rec
);
941 if( !type_engine_import_mfun( env
, func
) ) goto error
;
943 // look at or put sample directly in record buffer, do not pass go
944 func
= make_new_mfun( "float", "valueAt", LiSaMulti_ctrl_sample
);
945 func
->add_arg( "float", "val" );
946 func
->add_arg( "dur", "index" );
947 if( !type_engine_import_mfun( env
, func
) ) goto error
;
948 func
= make_new_mfun( "float", "valueAt", LiSaMulti_cget_sample
);
949 func
->add_arg( "dur", "index" );
950 if( !type_engine_import_mfun( env
, func
) ) goto error
;
953 func
= make_new_mfun( "float", "voiceGain", LiSaMulti_ctrl_voicegain
);
954 func
->add_arg( "int", "voice" );
955 func
->add_arg( "float", "val" );
956 if( !type_engine_import_mfun( env
, func
) ) goto error
;
957 func
= make_new_mfun( "float", "voiceGain", LiSaMulti_cget_voicegain
);
958 func
->add_arg( "int", "voice" );
960 // set record feedback coefficient
961 func
= make_new_mfun( "float", "feedback", LiSaMulti_ctrl_coeff
);
962 func
->add_arg( "float", "val" );
963 if( !type_engine_import_mfun( env
, func
) ) goto error
;
964 func
= make_new_mfun( "float", "feedback", LiSaMulti_cget_coeff
);
965 if( !type_engine_import_mfun( env
, func
) ) goto error
;
968 func
= make_new_mfun( "void", "clear", LiSaMulti_ctrl_clear
);
969 if( !type_engine_import_mfun( env
, func
) ) goto error
;
972 func
= make_new_mfun( "int", "getVoice", LiSaMulti_cget_voice
);
973 if( !type_engine_import_mfun( env
, func
) ) goto error
;
976 func
= make_new_mfun( "int", "maxVoices", LiSaMulti_ctrl_maxvoices
);
977 func
->add_arg( "int", "val" );
978 if( !type_engine_import_mfun( env
, func
) ) goto error
;
979 func
= make_new_mfun( "int", "maxVoices", LiSaMulti_cget_maxvoices
);
980 if( !type_engine_import_mfun( env
, func
) ) goto error
;
983 func
= make_new_mfun( "void", "rampUp", LiSaMulti_ctrl_rampup
);
984 func
->add_arg( "int", "voice" );
985 func
->add_arg( "dur", "val" );
986 if( !type_engine_import_mfun( env
, func
) ) goto error
;
988 func
= make_new_mfun( "void", "rampDown", LiSaMulti_ctrl_rampdown
);
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( "dur", "recRamp", LiSaMulti_ctrl_rec_ramplen
);
994 func
->add_arg( "dur", "val" );
995 if( !type_engine_import_mfun( env
, func
) ) goto error
;
997 func
= make_new_mfun( "void", "rampUp", LiSaMulti_ctrl_rampup0
);
998 func
->add_arg( "dur", "val" );
999 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1001 func
= make_new_mfun( "void", "rampDown", LiSaMulti_ctrl_rampdown0
);
1002 func
->add_arg( "dur", "val" );
1003 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1006 func
= make_new_mfun( "dur", "value", LiSaMulti_cget_value
);
1007 func
->add_arg( "int", "voice" );
1008 func
->add_arg( "dur", "val" );
1009 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1010 func
= make_new_mfun( "dur", "value", LiSaMulti_cget_value0
);
1011 func
->add_arg( "dur", "val" );
1012 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1015 func
= make_new_mfun( "int", "track", LiSaMulti_ctrl_track
);
1016 func
->add_arg( "int", "val" );
1017 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1018 func
= make_new_mfun( "int", "track", LiSaMulti_cget_track
);
1019 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1022 func
= make_new_mfun( "int", "sync", LiSaMulti_ctrl_track
);
1023 func
->add_arg( "int", "val" );
1024 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1025 func
= make_new_mfun( "int", "sync", LiSaMulti_cget_track
);
1026 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1029 func
= make_new_mfun( "int", "sync", LiSaMulti_ctrl_track
);
1030 func
->add_arg( "int", "val" );
1031 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1032 func
= make_new_mfun( "int", "sync", LiSaMulti_cget_track
);
1033 if( !type_engine_import_mfun( env
, func
) ) goto error
;
1035 // end the class import
1036 type_engine_import_class_end( env
);
1042 // end the class import
1043 type_engine_import_class_end( env
);
1051 //-----------------------------------------------------------------------------
1052 // name: multi_ctor()
1054 //-----------------------------------------------------------------------------
1055 CK_DLL_CTOR( multi_ctor
)
1063 //-----------------------------------------------------------------------------
1064 // name: multi_cget_chan()
1066 //-----------------------------------------------------------------------------
1067 CK_DLL_CGET( multi_cget_chan
)
1070 Chuck_UGen
* ugen
= (Chuck_UGen
*)SELF
;
1072 t_CKINT index
= GET_NEXT_INT( ARGS
);
1074 RETURN
->v_object
= index
>= 0 && index
< ugen
->m_multi_chan_size
?
1075 ugen
->m_multi_chan
[index
] : NULL
;
1081 //-----------------------------------------------------------------------------
1082 // name: stereo_ctor()
1084 //-----------------------------------------------------------------------------
1085 CK_DLL_CTOR( stereo_ctor
)
1088 Chuck_UGen
* ugen
= (Chuck_UGen
*)SELF
;
1091 if( ugen
->m_multi_chan_size
)
1094 OBJ_MEMBER_UINT(SELF
, stereo_offset_left
) = (t_CKUINT
)(ugen
->m_multi_chan
[0]);
1096 OBJ_MEMBER_UINT(SELF
, stereo_offset_right
) = (t_CKUINT
)(ugen
->m_multi_chan
[1]);
1100 // set left and right to self
1101 OBJ_MEMBER_UINT(SELF
, stereo_offset_left
) = (t_CKUINT
)ugen
;
1102 OBJ_MEMBER_UINT(SELF
, stereo_offset_right
) = (t_CKUINT
)ugen
;
1109 //-----------------------------------------------------------------------------
1110 // name: stereo_ctrl_pan()
1112 //-----------------------------------------------------------------------------
1113 CK_DLL_CTRL( stereo_ctrl_pan
)
1115 Chuck_UGen
* ugen
= (Chuck_UGen
* )SELF
;
1116 Chuck_UGen
* left
= ugen
->m_multi_chan
[0];
1117 Chuck_UGen
* right
= ugen
->m_multi_chan
[1];
1119 t_CKFLOAT pan
= GET_CK_FLOAT(ARGS
);
1121 if( pan
< -1.0 ) pan
= -1.0;
1122 else if( pan
> 1.0 ) pan
= 1.0;
1124 OBJ_MEMBER_FLOAT(SELF
, stereo_offset_pan
) = pan
;
1126 left
->m_pan
= pan
< 0.0 ? 1.0 : 1.0 - pan
;
1127 right
->m_pan
= pan
> 0.0 ? 1.0 : 1.0 + pan
;
1129 RETURN
->v_float
= pan
;
1135 //-----------------------------------------------------------------------------
1136 // name: stereo_cget_pan()
1138 //-----------------------------------------------------------------------------
1139 CK_DLL_CGET( stereo_cget_pan
)
1141 RETURN
->v_float
= OBJ_MEMBER_FLOAT(SELF
, stereo_offset_pan
);
1147 //-----------------------------------------------------------------------------
1150 //-----------------------------------------------------------------------------
1151 CK_DLL_TICK( dac_tick
)
1153 *out
= in
; return TRUE
;
1159 //-----------------------------------------------------------------------------
1160 // name: bunghole_tick
1162 //-----------------------------------------------------------------------------
1163 CK_DLL_TICK( bunghole_tick
)
1165 *out
= 0.0f
; return 0;
1171 //-----------------------------------------------------------------------------
1172 // name: noise_tick()
1174 //-----------------------------------------------------------------------------
1175 CK_DLL_TICK( noise_tick
)
1177 *out
= -1.0 + 2.0 * (SAMPLE
)rand() / RAND_MAX
;
1182 enum { NOISE_WHITE
=0, NOISE_PINK
, NOISE_BROWN
, NOISE_FBM
, NOISE_FLIP
, NOISE_XOR
};
1191 t_CKINT
* pink_array
;
1207 scale
= 2.0 / (double) RAND_MAX
;
1210 t_CKINT randt
= RAND_MAX
;
1212 fprob
= (t_CKINT
)( (double)RAND_MAX
* 1.0 / 32.0 );
1213 while ( randt
> 0 ) {
1217 // fprintf(stderr, "random bits - %d", rand_bits );
1224 void tick( t_CKTIME now
, SAMPLE
* out
);
1225 void setMode(char * c
);
1227 t_CKINT
pink_tick( SAMPLE
* out
);
1228 t_CKINT
brown_tick( SAMPLE
* out
);
1229 t_CKINT
xor_tick( SAMPLE
* out
);
1230 t_CKINT
flip_tick( SAMPLE
* out
);
1231 t_CKINT
fbm_tick( SAMPLE
* out
);
1235 CK_DLL_CTOR( cnoise_ctor
)
1237 OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
) = (t_CKUINT
)new CNoise_Data
;
1240 CK_DLL_DTOR( cnoise_dtor
)
1242 delete (CNoise_Data
*)OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
);
1243 OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
) = 0;
1246 CK_DLL_TICK( cnoise_tick
)
1248 CNoise_Data
* d
= ( CNoise_Data
* )OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
);
1251 return noise_tick(SELF
,in
,out
,SHRED
);
1254 return d
->pink_tick(out
);
1257 return d
->brown_tick(out
);
1260 return d
->xor_tick(out
);
1263 return d
->flip_tick(out
);
1266 return d
->fbm_tick(out
);
1272 t_CKINT
CNoise_Data::pink_tick( SAMPLE
* out
)
1274 //based on Voss-McCartney
1276 if ( pink_array
== NULL
) {
1277 pink_array
= (t_CKINT
*) malloc ( sizeof ( t_CKINT
) * pink_depth
);
1279 for ( t_CKINT i
= 0 ; i
< pink_depth
; i
++ ) { pink_array
[i
] = rand(); last
+= pink_array
[i
]; }
1280 scale
= 2.0 / ((double)RAND_MAX
* ( pink_depth
+ 1.0 ) );
1282 // fprintf( stderr, "scale %f %f %d %d \n", scale, bias, RAND_MAX, pink_depth + 1 );
1287 //count trailing zeroes
1288 while ( pind
< pink_depth
&& ! (counter
& ( 1 << pind
) ) ) pind
++;
1290 // fprintf (stderr, "counter %d pink - %d \n", counter, pind );
1292 if ( pind
< pink_depth
) {
1293 t_CKINT diff
= rand() - pink_array
[pind
];
1294 pink_array
[pind
] += diff
;
1298 *out
= bias
+ scale
* ( rand() + last
);
1300 if ( pink_rand
) counter
= rand();
1304 t_CKINT
CNoise_Data::xor_tick( SAMPLE
* out
)
1307 for ( t_CKINT i
= 0; i
< rand_bits
; i
++ )
1308 if ( rand() <= fprob
)
1311 *out
= bias
+ scale
* (SAMPLE
)last
;
1315 t_CKINT
CNoise_Data::flip_tick( SAMPLE
* out
)
1317 t_CKINT ind
= (t_CKINT
) ( (double) rand_bits
* rand() / ( RAND_MAX
+ 1.0 ) );
1319 last
= last
^ ( 1 << ind
);
1320 // fprintf ( stderr, "ind - %d %d %f %f", ind, last, bias, scale );
1321 *out
= bias
+ scale
* (SAMPLE
)last
;
1326 CNoise_Data::brown_tick( SAMPLE
* out
) {
1327 //brownian noise function..later!
1333 CNoise_Data::fbm_tick( SAMPLE
* out
) {
1334 //non-brownian noise function..later!
1340 CNoise_Data::setMode( char * c
) {
1341 if ( strcmp ( c
, "white" ) == 0 ) {
1342 // fprintf(stderr, "white noise\n");
1344 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1347 if ( strcmp ( c
, "pink" ) == 0 ) {
1348 // fprintf(stderr, "pink noise\n");
1350 scale
= 2.0 / (double)(RAND_MAX
* ( pink_depth
+ 1 ) );
1353 if ( strcmp ( c
, "flip" ) == 0) {
1354 // fprintf(stderr, "bitflip noise\n");
1356 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1359 if ( strcmp ( c
, "xor" ) == 0) {
1360 // fprintf(stderr, "xor noise\n");
1362 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1365 if ( strcmp ( c
, "brown" ) == 0) {
1366 // fprintf(stderr, "brownian noise\n");
1368 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1371 if ( strcmp ( c
, "fbm" ) == 0) {
1372 // fprintf(stderr, "fbm noise\n");
1374 scale
= 2.0 / (t_CKFLOAT
)RAND_MAX
;
1380 CK_DLL_CTRL( cnoise_ctrl_mode
)
1382 CNoise_Data
* d
= ( CNoise_Data
* )OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
);
1383 char * mode
= *(char **)GET_CK_STRING(ARGS
);
1387 CK_DLL_CTRL( cnoise_ctrl_fprob
)
1389 CNoise_Data
* d
= ( CNoise_Data
* )OBJ_MEMBER_UINT(SELF
, cnoise_offset_data
);
1390 t_CKFLOAT p
= GET_CK_FLOAT(ARGS
);
1391 d
->fprob
= (t_CKINT
) ( (double)RAND_MAX
* p
);
1396 //-----------------------------------------------------------------------------
1397 // name: struct Pulse_Data
1399 //-----------------------------------------------------------------------------
1404 Pulse_Data( ) { value
= 1.0f
; when
= 0; }
1408 //-----------------------------------------------------------------------------
1409 // name: impulse_ctor()
1411 //-----------------------------------------------------------------------------
1412 CK_DLL_CTOR( impulse_ctor
)
1414 // return data to be used later
1415 OBJ_MEMBER_UINT(SELF
, impulse_offset_data
) = (t_CKUINT
)new Pulse_Data
;
1421 //-----------------------------------------------------------------------------
1422 // name: impulse_dtor()
1424 //-----------------------------------------------------------------------------
1425 CK_DLL_DTOR( impulse_dtor
)
1428 delete (Pulse_Data
*)OBJ_MEMBER_UINT(SELF
, impulse_offset_data
);
1429 OBJ_MEMBER_UINT(SELF
, impulse_offset_data
) = 0;
1435 //-----------------------------------------------------------------------------
1436 // name: impulse_tick()
1438 //-----------------------------------------------------------------------------
1439 CK_DLL_TICK( impulse_tick
)
1441 Pulse_Data
* d
= (Pulse_Data
*)OBJ_MEMBER_UINT(SELF
, impulse_offset_data
);
1455 //-----------------------------------------------------------------------------
1456 // name: impulse_ctrl_next()
1458 //-----------------------------------------------------------------------------
1459 CK_DLL_CTRL( impulse_ctrl_next
)
1461 Pulse_Data
* d
= (Pulse_Data
*)OBJ_MEMBER_UINT(SELF
, impulse_offset_data
);
1462 d
->value
= (SAMPLE
)GET_CK_FLOAT(ARGS
);
1464 RETURN
->v_float
= (t_CKFLOAT
)d
->value
;
1470 //-----------------------------------------------------------------------------
1471 // name: impulse_cget_next()
1473 //-----------------------------------------------------------------------------
1474 CK_DLL_CGET( impulse_cget_next
)
1476 Pulse_Data
* d
= (Pulse_Data
*)OBJ_MEMBER_UINT(SELF
, impulse_offset_data
);
1477 RETURN
->v_float
= (t_CKFLOAT
)d
->value
;
1483 //-----------------------------------------------------------------------------
1484 // name: step_ctor()
1486 //-----------------------------------------------------------------------------
1487 CK_DLL_CTOR( step_ctor
)
1489 // return data to be used later
1490 OBJ_MEMBER_UINT(SELF
, step_offset_data
) = (t_CKUINT
)new SAMPLE( 1.0f
);
1496 //-----------------------------------------------------------------------------
1497 // name: step_dtor()
1499 //-----------------------------------------------------------------------------
1500 CK_DLL_DTOR( step_dtor
)
1503 delete (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, step_offset_data
);
1504 OBJ_MEMBER_UINT(SELF
, step_offset_data
) = 0;
1508 //-----------------------------------------------------------------------------
1509 // name: step_tick()
1511 //-----------------------------------------------------------------------------
1512 CK_DLL_TICK( step_tick
)
1514 SAMPLE
* d
= (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, step_offset_data
);
1521 //-----------------------------------------------------------------------------
1522 // name: step_ctrl_next()
1524 //-----------------------------------------------------------------------------
1525 CK_DLL_CTRL( step_ctrl_next
)
1527 SAMPLE
* d
= (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, step_offset_data
);
1528 *d
= (SAMPLE
)GET_CK_FLOAT(ARGS
);
1529 RETURN
->v_float
= (t_CKFLOAT
)(*d
);
1533 //-----------------------------------------------------------------------------
1534 // name: step_cget_next()
1536 //-----------------------------------------------------------------------------
1537 CK_DLL_CGET( step_cget_next
)
1539 SAMPLE
* d
= (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, step_offset_data
);
1540 RETURN
->v_float
= (t_CKFLOAT
)(*d
);
1546 //-----------------------------------------------------------------------------
1547 // name: halfrect_tick()
1549 //-----------------------------------------------------------------------------
1550 CK_DLL_TICK( halfrect_tick
)
1552 *out
= in
> 0.0f
? in
: 0.0f
;
1559 //-----------------------------------------------------------------------------
1560 // name: fullrect_tick()
1562 //-----------------------------------------------------------------------------
1563 CK_DLL_TICK( fullrect_tick
)
1565 *out
= in
>= 0.0f
? in
: -in
;
1572 //-----------------------------------------------------------------------------
1573 // name: zerox_ctor()
1575 //-----------------------------------------------------------------------------
1576 CK_DLL_CTOR( zerox_ctor
)
1578 OBJ_MEMBER_UINT(SELF
, zerox_offset_data
) = (t_CKUINT
)new SAMPLE( 0.0f
);
1582 //-----------------------------------------------------------------------------
1583 // name: zerox_dtor()
1585 //-----------------------------------------------------------------------------
1586 CK_DLL_DTOR( zerox_dtor
)
1588 delete (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, zerox_offset_data
);
1589 OBJ_MEMBER_UINT(SELF
, zerox_offset_data
) = 0;
1593 #define __SGN(x) (x >= 0.0f ? 1.0f : -1.0f )
1594 //-----------------------------------------------------------------------------
1595 // name: zerox_tick()
1597 //-----------------------------------------------------------------------------
1598 CK_DLL_TICK( zerox_tick
)
1600 SAMPLE
* d
= (SAMPLE
*)OBJ_MEMBER_UINT(SELF
, zerox_offset_data
);
1601 *out
= __SGN(in
) != __SGN(*d
);
1619 double readpos
; //readpos ( moves at constant speed, sample per sample
1620 double writepos
; // relative to read position
1622 t_CKTIME offset
; // distance between read and write
1624 t_CKDUR offset_start
;
1625 t_CKDUR offset_target
;
1627 t_CKTIME move_end_time
; //target time
1628 t_CKDUR move_duration
; //time we started shift
1631 t_CKDUR last_offset
;
1644 bufsize
= 2 * g_srate
;
1645 buffer
= ( SAMPLE
* ) realloc ( NULL
, sizeof ( SAMPLE
) * bufsize
);
1648 for ( i
= 0 ; i
< bufsize
; i
++ ) buffer
[i
] = 0;
1649 for ( i
= 0 ; i
< 3 ; i
++ ) { acoeff
[i
] = 0; bcoeff
[i
] = 0; }
1663 offset_target
= 0.0;
1665 move_duration
= 1.0;
1666 move_end_time
= 0.0;
1676 SAFE_DELETE_ARRAY( buffer
);
1680 CK_DLL_CTOR( delayp_ctor
)
1682 OBJ_MEMBER_UINT(SELF
, delayp_offset_data
) = (t_CKUINT
)new delayp_data
;
1685 CK_DLL_DTOR( delayp_dtor
)
1687 delayp_data
* d
= (delayp_data
*)OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1689 OBJ_MEMBER_UINT(SELF
, delayp_offset_data
) = 0;
1692 CK_DLL_PMSG( delayp_pmsg
)
1697 CK_DLL_TICK( delayp_tick
)
1699 delayp_data
* d
= (delayp_data
*)OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1700 if ( !d
->buffer
) return FALSE
;
1703 d
->now
= ((Chuck_UGen
*)SELF
)->shred
->vm_ref
->shreduler()->now_system
;
1705 //calculate new write-offset position ( we interpolate if we've been assigned a new write-offset )
1706 if ( d
->now
>= d
->move_end_time
|| d
->move_duration
== 0 ) d
->offset
= d
->offset_target
;
1708 double dt
= 1.0 + ( d
->now
- d
->move_end_time
) / ( d
->move_duration
);
1709 d
->offset
= d
->offset_start
+ dt
* ( d
->offset_target
- d
->offset_start
);
1710 // fprintf (stderr, "dt %f, off %f , start %f target %f\n", dt, d->writeoff, d->writeoff_start, d->writeoff_target );
1713 //find locations in buffer...
1714 double write
= (d
->readpos
) + d
->offset
;
1715 double last_write
= (d
->readpos
- 1.0) + d
->last_offset
;
1717 //linear interpolation. will introduce some lowpass/aliasing.
1718 double write_delta
= write
- last_write
;
1719 double sample_delta
= in
- d
->last_sample
;
1721 double duck_constant
= 0.69;
1724 double gee
= fabs(write_delta
) - 1.0;
1727 double head_contact
= ( gee
> 0 ) ? exp ( - duck_constant
* gee
) : 1.0;
1728 t_CKINT i
, smin
, smax
, sampi
;
1730 if ( write_delta
>= 0 ) { //forward.
1731 smin
= (t_CKINT
) floor ( last_write
);
1732 smax
= (t_CKINT
) floor ( write
);
1733 for ( i
= smin
+1 ; i
<= smax
; i
++ ) {
1734 sampf
= d
->last_sample
+ sample_delta
* ( double(i
) - last_write
) / write_delta
;
1735 sampi
= ( i
+ d
->bufsize
* 2 ) % d
->bufsize
;
1737 if ( d
->lasti
== sampi
) {
1738 fprintf( stderr
, "[chuck](via Curve): over!\n");
1742 d
->buffer
[sampi
] += sampf
* head_contact
;
1745 else { //moving in reverse
1746 smin
= (t_CKINT
) floor ( write
);
1747 smax
= (t_CKINT
) floor ( last_write
);
1748 for ( i
= smin
+1 ; i
<= smax
; i
++ ) {
1749 sampf
= d
->last_sample
+ sample_delta
* ( double(i
) - last_write
) / write_delta
;
1750 sampi
= ( i
+ d
->bufsize
* 2 ) % d
->bufsize
;
1752 if ( d
->lasti
== sampi
) {
1753 fprintf(stderr
, "[chuck](via Curve): over!\n");
1757 d
->buffer
[sampi
] += sampf
* head_contact
;
1762 d
->last_offset
= d
->offset
;
1763 d
->last_sample
= in
;
1766 //output should go through a dc blocking filter, for cases where
1767 //we are zipping around in the buffer leaving a fairly constant
1770 //output last sample
1772 t_CKINT rpos
= (t_CKINT
) fmod( d
->readpos
, d
->bufsize
) ;
1774 // *out = d->buffer[rpos];
1777 // did i try to write a dc blocking filter?
1778 d->outputs[0] = 0.0;
1779 d->inputs [0] = d->buffer[rpos];
1781 d->outputs[0] += d->bcoeff[1] * d->inputs[1];
1782 d->inputs [1] = d->inputs[0];
1784 d->outputs[0] += d->bcoeff[0] * d->inputs[0];
1786 d->outputs[0] += -d->acoeff[1] * d->outputs[1];
1787 d->outputs[1] = d->outputs[0];
1789 //clear at readpos ( write doesn't !)
1790 *out = d->outputs[0];
1793 *out
= d
->buffer
[rpos
];
1795 d
->buffer
[rpos
] = 0; //clear once it's been read
1796 d
->readpos
= fmod ( d
->readpos
+ 1.0 , double( d
->bufsize
) );
1802 CK_DLL_CTRL( delayp_ctrl_delay
)
1804 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1805 t_CKDUR target
= GET_CK_DUR(ARGS
); // rate
1808 if ( target
!= d
->offset_target
) {
1809 if ( target
> d
->bufsize
) {
1810 fprintf( stderr
, "[chuck](via delayp): delay time %f over max! set max first!\n", target
);
1813 d
->offset_target
= target
;
1814 d
->offset_start
= d
->last_offset
;
1816 t_CKTIME snow
= ((Chuck_UGen
*)SELF
)->shred
->now
;
1817 d
->move_end_time
= snow
+ d
->move_duration
;
1819 RETURN
->v_dur
= d
->last_offset
; // TODO:
1822 CK_DLL_CGET( delayp_cget_delay
)
1824 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1825 //SET_NEXT_DUR( out, d->writeoff_last );
1826 RETURN
->v_dur
= d
->last_offset
; // TODO:
1829 CK_DLL_CTRL( delayp_ctrl_window
)
1831 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1832 t_CKDUR window
= GET_CK_DUR(ARGS
); // rate
1833 if ( window
>= 0 ) {
1834 d
->move_duration
= window
;
1835 //fprintf ( stderr, "set window time %f , %f , %d \n", d->writeoff_window_time, d->writeoff, d->bufsize );
1837 RETURN
->v_dur
= d
->move_duration
; // TODO:
1840 CK_DLL_CGET( delayp_cget_window
)
1842 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1843 RETURN
->v_dur
= d
->move_duration
; // TODO:
1847 CK_DLL_CTRL( delayp_ctrl_max
)
1849 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1850 t_CKDUR nmax
= GET_CK_DUR(ARGS
); // rate
1851 if ( d
->bufsize
!= (t_CKINT
)nmax
&& nmax
> 1.0 ) {
1852 d
->bufsize
= (t_CKINT
)(nmax
+.5);
1853 d
->buffer
= ( SAMPLE
* ) realloc ( d
->buffer
, sizeof ( SAMPLE
) * d
->bufsize
);
1854 for ( t_CKINT i
= 0; i
< d
->bufsize
; i
++ ) d
->buffer
[i
] = 0;
1856 RETURN
->v_dur
= d
->bufsize
; // TODO??
1859 CK_DLL_CGET( delayp_cget_max
)
1861 delayp_data
* d
= ( delayp_data
* ) OBJ_MEMBER_UINT(SELF
, delayp_offset_data
);
1862 //SET_NEXT_DUR( out, (t_CKDUR) d->bufsize );
1863 RETURN
->v_dur
= d
->bufsize
;
1866 //-----------------------------------------------------------------------------
1869 //-----------------------------------------------------------------------------
1870 enum { SNDBUF_DROP
= 0, SNDBUF_INTERP
, SNDBUF_SINC
};
1873 #define WIDTH 16 /* this controls the number of neighboring samples
1874 which are used to interpolate the new samples. The
1875 processing time is linearly related to this width */
1876 #define DELAY_SIZE 140
1878 #define USE_TABLE TRUE /* this controls whether a linearly interpolated lookup
1879 table is used for sinc function calculation, or the
1880 sinc is calculated by floating point trig function calls. */
1882 #define USE_INTERP TRUE /* this controls whether the table is linear
1883 interpolated or not. If you re not using the
1884 table, this has no effect */
1886 #define SAMPLES_PER_ZERO_CROSSING 32 /* this defines how finely the sinc function
1887 is sampled for storage in the table */
1889 #ifdef CK_SNDBUF_MEMORY_BUFFER
1890 //------------------------------------------------------------------------------
1891 // name: MultiBuffer
1892 // desc: presents multiple buffers in memory as a single sequential logical
1893 // buffer, for constant time reallocing. tries to be as discreet as possible,
1894 // so you can basically use it like a pointer. optimized for iterative access,
1895 // as random access has T = O(bufsize)
1896 //------------------------------------------------------------------------------
1897 template< class _type
>
1917 void resize( size_t size
)
1919 assert( size
> m_size
); // for now
1920 size_t new_buffer_size
= size
- m_size
;
1923 new_extent
.position
= new _type
[new_buffer_size
];
1924 new_extent
.length
= new_buffer_size
;
1925 m_bufs
.push_back( new_extent
);
1931 // delete everything
1932 size_t i
, len
= m_bufs
.size();
1933 for( i
= 0; i
< len
; i
++ )
1934 delete[] m_bufs
[i
].position
;
1949 Pointer( MultiBuffer
* mb
)
1957 Pointer( const Pointer
& mbp
)\v
1960 m_lpos
= mbp
.m_lpos
;
1961 m_extent
= mbp
.m_extent
;
1962 m_extpos
= mbp
.m_extpos
;
1965 Pointer
& operator=( MultiBuffer
& mb
)
1975 Pointer
& operator=( const Pointer
& mbp
)
1978 m_lpos
= mbp
.m_lpos
;
1979 m_extent
= mbp
.m_extent
;
1980 m_extpos
= mbp
.m_extpos
;
1985 Pointer
& operator=( size_t i
)
1994 return m_mb
->m_bufs
[m_extent
].position
[m_extpos
];
1997 Pointer
operator+( size_t i
) const
1999 Pointer
mbp( *this );
2004 Pointer
operator++( int )
2006 Pointer mbp
= *this;
2007 this->increment( 1 );
2011 bool operator>=( const Pointer
& mbp
) const
2013 return ( m_lpos
>= mbp
.m_lpos
);
2016 bool operator>=( const size_t i
) const
2018 return ( m_lpos
>= i
);
2021 void increment( size_t i
)
2024 if( m_lpos
>= (m_mb
->m_size
) )
2026 m_extent
= m_mb
->m_bufs
.size();
2027 m_extpos
= m_lpos
- m_mb
->m_size
;
2031 extent ext_current
= m_mb
->m_bufs
[m_extent
];
2033 while( i
>= ext_current
.length
)
2035 i
-= ext_current
.length
;
2037 ext_current
= m_mb
->m_bufs
[m_extent
];
2053 size_t m_lpos
; // position in logical buffer
2054 size_t m_extent
; // current extent
2055 size_t m_extpos
; // position within the extent
2066 /* data shared by a set of MultiBuffers */
2067 vector
< extent
> m_bufs
; // array of sequentially allocated buffers
2068 size_t m_size
; // overall size of total memory represented
2070 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2072 // data for each sndbuf
2076 t_CKUINT num_samples
;
2077 t_CKUINT num_channels
;
2078 t_CKUINT num_frames
;
2079 t_CKUINT samplerate
;
2082 t_CKUINT chunks_read
;
2083 t_CKUINT chunks_total
;
2084 t_CKUINT chunks_size
;
2089 t_CKFLOAT sampleratio
;
2091 t_CKFLOAT rate_factor
;
2096 bool sinc_table_built
;
2097 bool sinc_use_table
;
2098 bool sinc_use_interp
;
2099 t_CKINT sinc_samples_per_zero_crossing
;
2101 double * sinc_table
;
2103 #ifdef CK_SNDBUF_MEMORY_BUFFER
2104 MultiBuffer
< SAMPLE
> mb_buffer
;
2105 t_CKUINT mb_max_samples
;
2106 MultiBuffer
< SAMPLE
>::Pointer mb_record_position
;
2107 MultiBuffer
< SAMPLE
>::Pointer mb_playback_position
;
2108 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2116 interp
= SNDBUF_INTERP
;
2134 sinc_table_built
= false;
2135 sinc_use_table
= USE_TABLE
;
2136 sinc_use_interp
= USE_INTERP
;
2138 sinc_samples_per_zero_crossing
= SAMPLES_PER_ZERO_CROSSING
;
2141 #ifdef CK_SNDBUF_MEMORY_BUFFER
2142 mb_buffer
= MultiBuffer
< SAMPLE
>();
2143 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2151 SAFE_DELETE_ARRAY( buffer
);
2152 SAFE_DELETE_ARRAY( chunk_table
);
2157 double sndbuf_sinc( sndbuf_data
* d
, double x
);
2158 double sndbuf_t_sinc( sndbuf_data
* d
, double x
);
2159 void sndbuf_make_sinc( sndbuf_data
* d
);
2160 void sndbuf_sinc_interpolate( sndbuf_data
* d
, SAMPLE
* out
);
2162 CK_DLL_CTOR( sndbuf_ctor
)
2164 OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
) = (t_CKUINT
)new sndbuf_data
;
2167 CK_DLL_DTOR( sndbuf_dtor
)
2169 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2171 OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
) = 0;
2174 inline t_CKUINT
sndbuf_read( sndbuf_data
* d
, t_CKUINT offset
, t_CKUINT howmuch
)
2177 if( d
->fd
== NULL
) return 0;
2178 if( offset
>= d
->num_frames
) return 0;
2181 // EM_log( CK_LOG_FINE, "(sndbuf): reading %d:%d frames...", offset, howmuch );
2184 if( howmuch
> d
->num_frames
- offset
)
2185 howmuch
= d
->num_frames
- offset
;
2189 sf_seek( d
->fd
, offset
, SEEK_SET
);
2190 #if defined(CK_S_DOUBLE)
2191 n
= sf_readf_double( d
->fd
, d
->buffer
+offset
*d
->num_channels
, howmuch
);
2193 n
= sf_readf_float( d
->fd
, d
->buffer
+offset
*d
->num_channels
, howmuch
);
2196 d
->chunks_read
+= n
;
2199 if( d
->chunks_read
>= d
->num_frames
)
2202 EM_log( CK_LOG_INFO
, "(sndbuf): all frames read, closing file..." );
2210 inline t_CKINT
sndbuf_load( sndbuf_data
* d
, t_CKUINT where
)
2213 t_CKUINT bin
= (t_CKUINT
)(where
/ (t_CKFLOAT
)d
->chunks_size
);
2214 if( bin
>= d
->chunks_total
) return 0;
2217 if( d
->chunk_table
[bin
] ) return 0;
2220 t_CKINT ret
= sndbuf_read( d
, bin
*d
->chunks_size
, d
->chunks_size
);
2223 d
->chunk_table
[bin
] = true;
2226 // EM_log( CK_LOG_FINER, "chunk test: pos: %d bin: %d read:%d/%d", where, bin, d->chunks_read, d->num_frames );
2231 inline void sndbuf_setpos( sndbuf_data
*d
, double pos
)
2233 if( !d
->buffer
) return;
2237 // set curf within bounds
2240 while( d
->curf
>= d
->num_frames
) d
->curf
-= d
->num_frames
;
2241 while( d
->curf
< 0 ) d
->curf
+= d
->num_frames
;
2245 if( d
->curf
< 0 ) d
->curf
= 0;
2246 else if( d
->curf
>= d
->num_frames
) d
->curf
= d
->num_frames
;
2249 t_CKINT i
= (t_CKINT
)d
->curf
;
2251 if( d
->fd
!= NULL
) sndbuf_load( d
, i
);
2252 // sets curr to correct position ( account for channels )
2253 d
->curr
= d
->buffer
+ d
->chan
+ i
* d
->num_channels
;
2256 inline SAMPLE
sndbuf_sampleAt( sndbuf_data
* d
, t_CKINT pos
)
2259 t_CKINT nf
= d
->num_frames
;
2261 while( pos
> nf
) pos
-= nf
;
2262 while( pos
< 0 ) pos
+= nf
;
2265 if( pos
> nf
) pos
= nf
;
2266 if( pos
< 0 ) pos
= 0;
2269 t_CKUINT index
= d
->chan
+ pos
* d
->num_channels
;
2271 if( d
->fd
!= NULL
) sndbuf_load( d
, pos
);
2273 return d
->buffer
[index
];
2276 inline double sndbuf_getpos( sndbuf_data
* d
)
2278 if( !d
->buffer
) return 0;
2279 return floor(d
->curf
);
2282 CK_DLL_CTRL( sndbuf_ctrl_loop
)
2284 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2285 d
->loop
= GET_CK_INT(ARGS
);
2286 RETURN
->v_int
= d
->loop
; // TODO: Check (everything)
2289 CK_DLL_CGET( sndbuf_cget_loop
)
2291 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2292 RETURN
->v_int
= d
->loop
;
2295 // PRC's sinc interpolation function.. as found
2296 // http://www.cs.princeton.edu/courses/archive/spring03/cs325/src/TimeStuf/srconvrt.c
2298 // there's probably a lot in there that could be optimized, if we care to..
2300 // #define PI 3.14159265358979323846
2301 // wow... we are sensitive..
2303 inline double sndbuf_linear_interp( double * first
, double * second
, double * frac
);
2304 bool sinc_table_built
= false;
2306 void sndbuf_sinc_interpolate( sndbuf_data
*d
, SAMPLE
* out
)
2309 double factor
= d
->rate
;
2310 double time_now
= d
->curf
;
2311 double one_over_factor
;
2312 // UNUSED: double int_time = 0;
2313 // UNUSED: double last_time = 0;
2316 long time_i
= (long)time_now
;
2318 // bounds checking now in sampleAt function...
2319 if( factor
< 1.0 ) {
2320 for( j
= -d
->sinc_width
+ 1; j
< d
->sinc_width
; j
++ )
2322 temp1
+= sndbuf_sampleAt(d
,time_i
+j
) * sndbuf_sinc( d
, (double)j
);
2324 *out
= (SAMPLE
)temp1
;
2327 one_over_factor
= 1.0 / factor
;
2328 for( j
= -d
->sinc_width
+ 1; j
< d
->sinc_width
; j
++ ) {
2329 temp1
+= sndbuf_sampleAt(d
,time_i
+j
) * one_over_factor
* sndbuf_sinc( d
, one_over_factor
* (double)j
);
2331 *out
= (SAMPLE
)temp1
;
2335 void sndbuf_make_sinc( sndbuf_data
* d
)
2338 // fprintf(stderr, "building sinc table\n" );
2339 double temp
, win_freq
, win
;
2340 win_freq
= ONE_PI
/ d
->sinc_width
/ d
->sinc_samples_per_zero_crossing
;
2341 t_CKINT tabsize
= d
->sinc_width
* d
->sinc_samples_per_zero_crossing
;
2343 d
->sinc_table
= (double *) realloc( d
->sinc_table
, tabsize
* sizeof(double) );
2344 d
->sinc_table
[0] = 1.0;
2345 for( i
= 1; i
< tabsize
; i
++ ) {
2346 temp
= (double) i
* ONE_PI
/ d
->sinc_samples_per_zero_crossing
;
2347 d
->sinc_table
[i
] = (float)(sin(temp
) / temp
);
2348 win
= 0.5 + 0.5 * cos(win_freq
* i
);
2349 d
->sinc_table
[i
] *= (float)win
;
2351 d
->sinc_table_built
= true;
2354 inline double sndbuf_linear_interp( double first_number
, double second_number
, double fraction
)
2356 return (first_number
+ ((second_number
- first_number
) * fraction
));
2359 double sndbuf_t_sinc( sndbuf_data
* d
, double x
)
2363 if( !d
->sinc_table_built
) sndbuf_make_sinc(d
);
2364 if( fabs(x
) >= d
->sinc_width
-1 )
2367 temp
= fabs(x
) * (double) d
->sinc_samples_per_zero_crossing
;
2368 low
= (t_CKINT
)temp
; /* these are interpolation steps */
2369 if( d
->sinc_use_interp
) {
2370 delta
= temp
- low
; /* and can be ommited if desired */
2371 return sndbuf_linear_interp( d
->sinc_table
[low
], d
->sinc_table
[low
+ 1], delta
);
2373 else return d
->sinc_table
[low
];
2377 double sndbuf_sinc( sndbuf_data
* d
, double x
)
2381 if( d
->sinc_use_table
) return sndbuf_t_sinc(d
,x
);
2383 if( x
== 0.0 ) return 1.0;
2386 return sin(temp
) / (temp
);
2391 CK_DLL_TICK( sndbuf_tick
)
2393 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2395 #ifdef CK_SNDBUF_MEMORY_BUFFER
2396 // spencer's memory buffer stuff
2398 // no file open - memory buffer mode
2400 Chuck_UGen
* ugen
= (Chuck_UGen
*)SELF
;
2401 if( ugen
->m_num_src
)
2404 if( d
->mb_buffer
.size() == 0 )
2406 d
->mb_buffer
.resize( 44100 * 4 ); // default size: 4 seconds
2407 d
->mb_record_position
= d
->mb_buffer
;
2408 d
->mb_playback_position
= d
->mb_buffer
;
2411 if( d
->mb_record_position
>= d
->mb_buffer
.size() )
2412 d
->mb_buffer
.resize( d
->mb_buffer
.size() * 2 );
2414 *(d
->mb_record_position
++) = in
;
2417 if( d
->mb_buffer
.size() )
2419 if( d
->mb_playback_position
>= d
->mb_record_position
)
2422 d
->mb_playback_position
= 0;
2424 else if( ugen
->m_num_src
)
2434 *out
= *(d
->mb_playback_position
++);
2439 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2440 if( !d
->buffer
) return FALSE
;
2442 // we're ticking once per sample ( system )
2445 if( !d
->loop
&& d
->curr
>= d
->eob
+ d
->num_channels
) return FALSE
;
2448 if( d
->interp
== SNDBUF_DROP
)
2450 *out
= (SAMPLE
)( (*(d
->curr
)) ) ;
2452 else if( d
->interp
== SNDBUF_INTERP
)
2454 // samplewise linear interp
2455 double alpha
= d
->curf
- floor(d
->curf
);
2456 *out
= (SAMPLE
)( (*(d
->curr
)) ) ;
2457 *out
+= (float)alpha
* ( sndbuf_sampleAt(d
, (long)d
->curf
+1 ) - *out
);
2459 else if( d
->interp
== SNDBUF_SINC
) {
2460 // do that fancy sinc function!
2461 sndbuf_sinc_interpolate(d
, out
);
2466 sndbuf_setpos(d
, d
->curf
);
2472 #include "util_raw.h"
2475 CK_DLL_CTRL( sndbuf_ctrl_read
)
2477 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2478 const char * filename
= GET_CK_STRING(ARGS
)->str
.c_str();
2482 delete [] d
->buffer
;
2486 if( d
->chunk_table
)
2488 delete [] d
->chunk_table
;
2489 d
->chunk_table
= NULL
;
2499 EM_log( CK_LOG_INFO
, "(sndbuf): reading '%s'...", filename
);
2502 if( strstr(filename
, "special:") )
2504 SAMPLE
* rawdata
= NULL
;
2505 t_CKUINT rawsize
= 0;
2506 t_CKUINT srate
= 22050;
2509 if( strstr(filename
, "special:sinewave") ) {
2510 rawsize
= 1024; rawdata
= NULL
;
2512 else if( strstr(filename
, "special:ahh") ) {
2513 rawsize
= ahh_size
; rawdata
= ahh_data
;
2515 else if( strstr(filename
, "special:britestk") ) {
2516 rawsize
= britestk_size
; rawdata
= britestk_data
;
2518 else if( strstr(filename
, "special:dope") ) {
2519 rawsize
= dope_size
; rawdata
= dope_data
;
2521 else if( strstr(filename
, "special:eee") ) {
2522 rawsize
= eee_size
; rawdata
= eee_data
;
2524 else if( strstr(filename
, "special:fwavblnk") ) {
2525 rawsize
= fwavblnk_size
; rawdata
= fwavblnk_data
;
2527 else if( strstr(filename
, "special:halfwave") ) {
2528 rawsize
= halfwave_size
; rawdata
= halfwave_data
;
2530 else if( strstr(filename
, "special:impuls10") ) {
2531 rawsize
= impuls10_size
; rawdata
= impuls10_data
;
2533 else if( strstr(filename
, "special:impuls20") ) {
2534 rawsize
= impuls20_size
; rawdata
= impuls20_data
;
2536 else if( strstr(filename
, "special:impuls40") ) {
2537 rawsize
= impuls40_size
; rawdata
= impuls40_data
;
2539 else if( strstr(filename
, "special:mand1") ) {
2540 rawsize
= mand1_size
; rawdata
= mand1_data
;
2542 else if( strstr(filename
, "special:mandpluk") ) {
2543 rawsize
= mandpluk_size
; rawdata
= mandpluk_data
;
2545 else if( strstr(filename
, "special:marmstk1") ) {
2546 rawsize
= marmstk1_size
; rawdata
= marmstk1_data
;
2548 else if( strstr(filename
, "special:ooo") ) {
2549 rawsize
= ooo_size
; rawdata
= ooo_data
;
2551 else if( strstr(filename
, "special:peksblnk") ) {
2552 rawsize
= peksblnk_size
; rawdata
= peksblnk_data
;
2554 else if( strstr(filename
, "special:ppksblnk") ) {
2555 rawsize
= ppksblnk_size
; rawdata
= ppksblnk_data
;
2557 else if( strstr(filename
, "special:silence") ) {
2558 rawsize
= silence_size
; rawdata
= silence_data
;
2560 else if( strstr(filename
, "special:sineblnk") ) {
2561 rawsize
= sineblnk_size
; rawdata
= sineblnk_data
;
2563 else if( strstr(filename
, "special:sinewave") ) {
2564 rawsize
= sinewave_size
; rawdata
= sinewave_data
;
2566 else if( strstr(filename
, "special:snglpeak") ) {
2567 rawsize
= snglpeak_size
; rawdata
= snglpeak_data
;
2569 else if( strstr(filename
, "special:twopeaks") ) {
2570 rawsize
= twopeaks_size
; rawdata
= twopeaks_data
;
2572 else if( strstr(filename
, "special:glot_ahh") ) {
2573 rawsize
= glot_ahh_size
; rawdata
= glot_ahh_data
; srate
= 44100;
2575 else if( strstr(filename
, "special:glot_eee") ) {
2576 rawsize
= glot_eee_size
; rawdata
= glot_eee_data
; srate
= 44100;
2578 else if( strstr(filename
, "special:glot_ooo") ) {
2579 rawsize
= glot_ooo_size
; rawdata
= glot_ooo_data
; srate
= 44100;
2581 else if( strstr(filename
, "special:glot_pop") ) {
2582 rawsize
= glot_pop_size
; rawdata
= glot_pop_data
; srate
= 44100;
2585 d
->num_frames
= rawsize
;
2586 d
->num_channels
= 1;
2588 d
->samplerate
= srate
;
2589 d
->num_samples
= rawsize
;
2592 d
->chunks_read
= d
->num_frames
;
2595 d
->buffer
= new SAMPLE
[rawsize
+1];
2596 for( t_CKUINT j
= 0; j
< rawsize
; j
++ ) {
2597 d
->buffer
[j
] = (SAMPLE
)rawdata
[j
]/(SAMPLE
)SHRT_MAX
;
2600 else if( strstr(filename
, "special:sinewave") ) {
2601 d
->buffer
= new SAMPLE
[rawsize
+1];
2602 for( t_CKUINT j
= 0; j
< rawsize
; j
++ )
2603 d
->buffer
[j
] = sin(2*ONE_PI
*j
/rawsize
);
2606 fprintf( stderr
, "[chuck](via SndBuf): cannot load '%s'\n", filename
);
2610 d
->buffer
[rawsize
] = d
->buffer
[0];
2614 // stat the file first
2616 if( stat( filename
, &s
) )
2618 fprintf( stderr
, "[chuck](via SndBuf): cannot stat file '%s'...\n", filename
);
2625 const char * format
= (const char *)strrchr( filename
, '.');
2626 if( format
&& strcmp( format
, ".raw" ) == 0 )
2628 fprintf( stderr
, "[chuck](via SndBuf) %s :: type is '.raw'...\n assuming 16 bit signed mono (PCM)\n", filename
);
2629 info
.format
= SF_FORMAT_RAW
| SF_FORMAT_PCM_16
| SF_ENDIAN_CPU
;
2631 info
.samplerate
= 44100;
2635 d
->fd
= sf_open( filename
, SFM_READ
, &info
);
2636 t_CKINT er
= sf_error( d
->fd
);
2639 fprintf( stderr
, "[chuck](via SndBuf): sndfile error '%i' opening '%s'...\n", er
, filename
);
2640 fprintf( stderr
, "[chuck](via SndBuf): (reason: %s)\n", sf_strerror( d
->fd
) );
2641 if( d
->fd
) sf_close( d
->fd
);
2647 t_CKINT size
= info
.channels
* info
.frames
;
2648 d
->buffer
= new SAMPLE
[size
+info
.channels
];
2649 memset( d
->buffer
, 0, (size
+info
.channels
)*sizeof(SAMPLE
) );
2651 d
->num_frames
= info
.frames
;
2652 d
->num_channels
= info
.channels
;
2653 d
->samplerate
= info
.samplerate
;
2654 d
->num_samples
= size
;
2658 EM_log( CK_LOG_INFO
, "channels: %d", d
->num_channels
);
2659 EM_log( CK_LOG_INFO
, "frames: %d", d
->num_frames
);
2660 EM_log( CK_LOG_INFO
, "srate: %d", d
->samplerate
);
2661 EM_log( CK_LOG_INFO
, "chunks: %d", d
->chunks
);
2665 sf_seek( d
->fd
, 0, SEEK_SET
);
2672 t_CKUINT f
= sndbuf_read( d
, 0, d
->num_frames
);
2674 if( f
!= (t_CKUINT
)d
->num_frames
)
2676 fprintf( stderr
, "[chuck](via SndBuf): read %d rather than %d frames from %s\n",
2677 f
, size
, filename
);
2678 sf_close( d
->fd
); d
->fd
= NULL
;
2682 assert( d
->fd
== NULL
);
2687 d
->chunks_size
= d
->chunks
;
2688 d
->chunks_total
= d
->num_frames
/ d
->chunks
;
2689 d
->chunks_total
+= d
->num_frames
% d
->chunks
? 1 : 0;
2691 d
->chunk_table
= new bool[d
->chunks_total
];
2692 memset( d
->chunk_table
, 0, d
->chunks_total
* sizeof(bool) );
2695 // sndbuf_load( d, 0 );
2699 // d->interp = SNDBUF_INTERP;
2700 d
->sampleratio
= (double)d
->samplerate
/ (double)g_srate
;
2702 d
->rate
= d
->sampleratio
* d
->rate_factor
;
2703 d
->curr
= d
->buffer
;
2705 d
->eob
= d
->buffer
+ d
->num_samples
;
2708 CK_DLL_CTRL( sndbuf_ctrl_write
)
2710 #ifdef SPENCER_SNDBUF_WRITE
2711 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2712 const char * filename
= GET_CK_STRING(ARGS
)->str
.c_str();
2716 delete [] d
->buffer
;
2721 if( stat( filename
, &s
) )
2723 fprintf( stderr
, "[chuck](via SndBuf): cannot stat file '%s'...\n", filename
);
2727 d
->curr
= d
->buffer
;
2728 d
->eob
= d
->buffer
+ d
->num_samples
;
2733 CK_DLL_CTRL( sndbuf_ctrl_rate
)
2735 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2736 t_CKFLOAT rate
= GET_CK_FLOAT(ARGS
); // rate
2737 d
->rate
= rate
* d
->sampleratio
;
2738 d
->rate_factor
= rate
;
2739 RETURN
->v_float
= d
->rate_factor
; // TODO: (or not TODO:)
2742 CK_DLL_CGET( sndbuf_cget_rate
)
2744 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2745 RETURN
->v_float
= d
->rate_factor
;
2749 CK_DLL_CTRL( sndbuf_ctrl_freq
)
2751 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2752 t_CKFLOAT freq
= GET_CK_FLOAT(ARGS
); //hz
2754 d
->rate
= ( freq
* (double) d
->num_frames
/ (double) g_srate
);
2755 d
->rate_factor
= d
->rate
/ d
->sampleratio
;
2756 RETURN
->v_float
= d
->rate
* (t_CKFLOAT
) g_srate
/ ( (t_CKFLOAT
) d
->num_frames
); // TODO: really?
2759 CK_DLL_CGET( sndbuf_cget_freq
)
2761 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2762 RETURN
->v_float
= d
->rate
* (t_CKFLOAT
) g_srate
/ ( (t_CKFLOAT
) d
->num_frames
);
2765 CK_DLL_CTRL( sndbuf_ctrl_phase
)
2767 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2768 t_CKFLOAT phase
= GET_CK_FLOAT(ARGS
);
2769 sndbuf_setpos(d
, phase
* (double)d
->num_frames
);
2770 RETURN
->v_float
= (t_CKFLOAT
) d
->curf
/ (t_CKFLOAT
)d
->num_frames
; // TODO:
2773 CK_DLL_CGET( sndbuf_cget_phase
)
2775 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2776 //SET_NEXT_FLOAT( out, (t_CKFLOAT) d->curf / (t_CKFLOAT)d->num_frames );
2777 RETURN
->v_float
= (t_CKFLOAT
) d
->curf
/ (t_CKFLOAT
)d
->num_frames
;
2780 CK_DLL_CTRL( sndbuf_ctrl_channel
)
2782 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2783 unsigned long chan
= (unsigned long)GET_CK_INT(ARGS
);
2784 if ( chan
>= 0 && chan
< d
->num_channels
) {
2787 RETURN
->v_int
= (t_CKINT
)d
->chan
;
2790 CK_DLL_CGET( sndbuf_cget_channel
)
2792 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2793 //SET_NEXT_INT( out, d->chan );
2794 RETURN
->v_int
= (t_CKINT
)d
->chan
;
2797 CK_DLL_CTRL( sndbuf_ctrl_pos
)
2799 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2800 t_CKINT pos
= GET_CK_INT(ARGS
);
2801 #ifdef CK_SNDBUF_MEMORY_BUFFER
2802 if( pos
>= 0 && pos
< d
->mb_max_samples
)
2803 d
->mb_playback_position
= pos
;
2804 #endif /* CK_SNDBUF_MEMORY_BUFFER */
2805 sndbuf_setpos(d
, pos
);
2806 RETURN
->v_int
= (t_CKINT
)sndbuf_getpos(d
); // TODO TODO TODOOO
2809 CK_DLL_CGET( sndbuf_cget_pos
)
2811 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2812 RETURN
->v_int
= (t_CKINT
)sndbuf_getpos(d
);
2815 CK_DLL_CTRL( sndbuf_ctrl_interp
)
2817 sndbuf_data
* d
= ( sndbuf_data
* ) OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2818 t_CKINT interp
= GET_CK_INT(ARGS
);
2820 RETURN
->v_int
= d
->interp
;
2823 CK_DLL_CGET( sndbuf_cget_interp
)
2825 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2826 RETURN
->v_int
= d
->interp
;
2829 CK_DLL_CTRL( sndbuf_ctrl_chunks
)
2831 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2832 t_CKINT frames
= GET_NEXT_INT(ARGS
);
2833 d
->chunks
= frames
>= 0 ? frames
: 0;
2834 RETURN
->v_int
= d
->chunks
;
2837 CK_DLL_CGET( sndbuf_cget_chunks
)
2839 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2840 RETURN
->v_int
= d
->chunks
;
2843 CK_DLL_CTRL( sndbuf_ctrl_phase_offset
)
2845 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2846 t_CKFLOAT phase_offset
= GET_CK_FLOAT(ARGS
);
2847 sndbuf_setpos(d
, d
->curf
+ phase_offset
* (t_CKFLOAT
)d
->num_frames
);
2850 CK_DLL_CGET( sndbuf_cget_samples
)
2852 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2853 //SET_NEXT_INT( out, d->num_frames );
2854 RETURN
->v_int
= d
->num_frames
;
2857 CK_DLL_CGET( sndbuf_cget_length
)
2859 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2860 //SET_NEXT_DUR( out, (t_CKDUR)d->num_frames );
2861 RETURN
->v_dur
= (t_CKDUR
)d
->num_frames
/ d
->sampleratio
;
2864 CK_DLL_CGET( sndbuf_cget_channels
)
2866 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2867 //SET_NEXT_INT( out, d->num_channels );
2868 RETURN
->v_int
= d
->num_channels
;
2871 CK_DLL_CGET( sndbuf_cget_valueAt
)
2873 sndbuf_data
* d
= (sndbuf_data
*)OBJ_MEMBER_UINT(SELF
, sndbuf_offset_data
);
2874 t_CKINT i
= GET_CK_INT(ARGS
);
2875 if( d
->fd
) sndbuf_load( d
, i
);
2876 RETURN
->v_float
= ( i
> d
->num_frames
|| i
< 0 ) ? 0 : d
->buffer
[i
];
2883 const static t_CKDUR ms
;
2886 t_CKFLOAT slopeAbove
;
2887 t_CKFLOAT slopeBelow
;
2891 t_CKFLOAT xd
; //sidechain
2892 int externalSideInput
; // use input signal or a ctrl signal for env
2893 t_CKFLOAT sideInput
; // the ctrl signal for the envelope
2895 int count
; //diagnostic
2911 //set the time constants for rt, at, and tav
2912 static t_CKFLOAT
computeTimeConst(t_CKDUR t
) {
2913 //AT = 1 - e ^ (-2.2T/t<AT)
2914 //as per chuck_type.cpp, T(sampling period) = 1.0
2915 return 1.0 - exp( -2.2 / t
);
2918 static t_CKDUR
timeConstToDur(t_CKFLOAT x
) {
2919 return -2.2 / log(1.0 - x
);
2922 //setters for timing constants
2923 void setAttackTime(t_CKDUR t
);
2924 void setReleaseTime(t_CKDUR t
);
2927 void setRatio(t_CKFLOAT newRatio
);
2928 t_CKFLOAT
getRatio();
2931 const t_CKDUR
Dyno_Data::ms
= g_vm
->srate() * 1.0 / 1000.0;
2933 //setters for the timing constants
2934 void Dyno_Data::setAttackTime(t_CKDUR t
) {
2935 at
= computeTimeConst(t
);
2938 void Dyno_Data::setReleaseTime(t_CKDUR t
) {
2939 rt
= computeTimeConst(t
);
2942 void Dyno_Data::setRatio(t_CKFLOAT newRatio
) {
2943 this->slopeAbove
= 1.0 / newRatio
;
2944 this->slopeBelow
= 1.0;
2947 t_CKFLOAT
Dyno_Data::getRatio()
2949 return this->slopeBelow
/ this->slopeAbove
;
2952 //TODO: come up with better/good presets?
2954 //presets for the dynomics processor
2955 void Dyno_Data::limit() {
2956 slopeAbove
= 0.1; // 10:1 compression above thresh
2957 slopeBelow
= 1.0; // no compression below
2959 at
= computeTimeConst( 5.0 * ms
);
2960 rt
= computeTimeConst( 300.0 * ms
);
2961 externalSideInput
= 0;
2964 void Dyno_Data::compress() {
2965 slopeAbove
= 0.5; // 2:1 compression
2968 at
= computeTimeConst( 5.0 * ms
);
2969 rt
= computeTimeConst( 500.0 * ms
);
2970 externalSideInput
= 0;
2973 void Dyno_Data::gate() {
2975 slopeBelow
= 100000000; // infinity (more or less)
2977 at
= computeTimeConst( 11.0 * ms
);
2978 rt
= computeTimeConst( 100.0 * ms
);
2979 externalSideInput
= 0;
2982 void Dyno_Data::expand() {
2983 slopeAbove
= 2.0; // 1:2 expansion
2986 at
= computeTimeConst( 20.0 * ms
);
2987 rt
= computeTimeConst( 400.0 * ms
);
2988 externalSideInput
= 0;
2991 void Dyno_Data::duck() {
2992 slopeAbove
= 0.5; // when sideInput rises above thresh, gain starts going
2993 slopeBelow
= 1.0; // down. it'll drop more as sideInput gets louder.
2995 at
= computeTimeConst( 10.0 * ms
);
2996 rt
= computeTimeConst( 1000.0 * ms
);
2997 externalSideInput
= 1;
3001 //controls for the preset modes
3002 CK_DLL_CTRL( dyno_ctrl_limit
) {
3003 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3007 CK_DLL_CTRL( dyno_ctrl_compress
) {
3008 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3012 CK_DLL_CTRL( dyno_ctrl_gate
) {
3013 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3017 CK_DLL_CTRL( dyno_ctrl_expand
) {
3018 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3022 CK_DLL_CTRL( dyno_ctrl_duck
) {
3023 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3027 //additional controls: thresh
3028 CK_DLL_CTRL( dyno_ctrl_thresh
) {
3029 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3030 d
->thresh
= GET_CK_FLOAT(ARGS
);
3031 RETURN
->v_float
= (t_CKFLOAT
)d
->thresh
;
3034 CK_DLL_CGET( dyno_cget_thresh
) {
3035 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3036 RETURN
->v_float
= (t_CKFLOAT
)d
->thresh
;
3039 //additional controls: attackTime
3040 CK_DLL_CTRL( dyno_ctrl_attackTime
) {
3041 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3042 d
->setAttackTime( GET_CK_FLOAT(ARGS
) );
3043 RETURN
->v_dur
= d
->timeConstToDur(d
->at
);
3046 CK_DLL_CGET( dyno_cget_attackTime
) {
3047 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3048 RETURN
->v_dur
= d
->timeConstToDur(d
->at
);
3051 //additional controls: releaseTime
3052 CK_DLL_CTRL( dyno_ctrl_releaseTime
) {
3053 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3054 d
->setReleaseTime( GET_CK_FLOAT(ARGS
) );
3055 RETURN
->v_dur
= d
->timeConstToDur(d
->rt
);
3058 CK_DLL_CGET( dyno_cget_releaseTime
) {
3059 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3060 RETURN
->v_dur
= d
->timeConstToDur(d
->rt
);
3063 //additional controls: ratio
3064 CK_DLL_CTRL( dyno_ctrl_ratio
) {
3065 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3066 d
->setRatio( GET_CK_FLOAT(ARGS
) );
3067 RETURN
->v_float
= d
->getRatio();
3070 CK_DLL_CGET( dyno_cget_ratio
) {
3071 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3072 RETURN
->v_float
= d
->getRatio();
3075 //additional controls: slopeBelow
3076 CK_DLL_CTRL( dyno_ctrl_slopeBelow
) {
3077 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3078 d
->slopeBelow
= GET_CK_FLOAT(ARGS
);
3080 RETURN
->v_float
= d
->slopeBelow
;
3083 CK_DLL_CGET( dyno_cget_slopeBelow
) {
3084 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3085 RETURN
->v_float
= d
->slopeBelow
;
3088 //additional controls: slopeAbove
3089 CK_DLL_CTRL( dyno_ctrl_slopeAbove
) {
3090 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3091 d
->slopeAbove
= GET_CK_FLOAT(ARGS
);
3093 RETURN
->v_float
= d
->slopeAbove
;
3096 CK_DLL_CGET( dyno_cget_slopeAbove
) {
3097 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3098 RETURN
->v_float
= d
->slopeAbove
;
3101 //additional controls: sideInput
3102 CK_DLL_CTRL( dyno_ctrl_sideInput
) {
3103 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3104 d
->sideInput
= GET_CK_FLOAT(ARGS
);
3106 RETURN
->v_float
= d
->sideInput
;
3109 CK_DLL_CGET( dyno_cget_sideInput
) {
3110 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3111 RETURN
->v_float
= d
->sideInput
;
3114 //additional controls: externalSideInput
3115 CK_DLL_CTRL( dyno_ctrl_externalSideInput
) {
3116 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3117 d
->externalSideInput
= GET_CK_INT(ARGS
);
3119 RETURN
->v_int
= d
->externalSideInput
;
3122 CK_DLL_CGET( dyno_cget_externalSideInput
) {
3123 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3124 RETURN
->v_int
= d
->externalSideInput
;
3128 CK_DLL_CTOR( dyno_ctor
)
3130 OBJ_MEMBER_UINT(SELF
, dyno_offset_data
) = (t_CKUINT
)new Dyno_Data
;
3133 CK_DLL_DTOR( dyno_dtor
)
3135 delete (Dyno_Data
*)OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3136 OBJ_MEMBER_UINT(SELF
, dyno_offset_data
) = 0;
3139 // recomputes envelope, determines how the current amp envelope compares with
3140 // thresh, applies the appropriate new slope depending on how far above/below
3141 // the threshold the current envelope is.
3142 CK_DLL_TICK( dyno_tick
)
3144 Dyno_Data
* d
= ( Dyno_Data
* )OBJ_MEMBER_UINT(SELF
, dyno_offset_data
);
3146 // only change sideInput if we're not using an external ctrl signal.
3147 // otherwise we'll just use whatever the user sent us last as the ctrl signal
3148 if(!d
->externalSideInput
)
3149 d
->sideInput
= in
>= 0 ? in
: -in
;
3151 // 'a' is signal left after subtracting xd (to recompute sideChain envelope)
3152 double a
= d
->sideInput
- d
->xd
;
3153 // a is only needed if positive to pull the envelope up, not to bring it down
3155 // the attack/release (peak) exponential filter to guess envelope
3156 d
->xd
= d
->xd
* (1 - d
->rt
) + d
->at
* a
;
3158 // if you were to use the rms filter,
3159 // it would probably look, a sumpthin' like this
3160 // d->xd = TAV * in*in + (1+TAV) * d->xd
3162 // decide which slope to use, depending on whether we're below/above thresh
3163 double slope
= d
->xd
> d
->thresh
? d
->slopeAbove
: d
->slopeBelow
;
3164 // the gain function - apply the slope chosen above
3165 double f
= slope
== 1.0 ? 1.0 : pow( d
->xd
/ d
->thresh
, slope
- 1.0 );
3167 // apply the gain found above to input sample
3176 #define LiSa_MAXVOICES 200
3177 #define LiSa_MAXBUFSIZE 4410000
3178 //-----------------------------------------------------------------------------
3179 // name: LiSaMulti_data
3181 //-----------------------------------------------------------------------------
3182 struct LiSaMulti_data
3187 t_CKINT loop_start
[LiSa_MAXVOICES
], loop_end
[LiSa_MAXVOICES
], loop_end_rec
;
3188 t_CKINT rindex
; // record and play indices
3189 t_CKBOOL record
, looprec
, loopplay
[LiSa_MAXVOICES
], reset
, append
, play
[LiSa_MAXVOICES
], bi
[LiSa_MAXVOICES
];
3190 t_CKFLOAT coeff
; // feedback coeff
3191 t_CKFLOAT voiceGain
[LiSa_MAXVOICES
]; //gain control for each voice
3192 t_CKDOUBLE p_inc
[LiSa_MAXVOICES
], pindex
[LiSa_MAXVOICES
]; // playback increment
3195 t_CKDOUBLE rampup_len
[LiSa_MAXVOICES
], rampdown_len
[LiSa_MAXVOICES
], rec_ramplen
, rec_ramplen_inv
;
3196 t_CKDOUBLE rampup_len_inv
[LiSa_MAXVOICES
], rampdown_len_inv
[LiSa_MAXVOICES
];
3197 t_CKDOUBLE rampctr
[LiSa_MAXVOICES
];
3198 t_CKBOOL rampup
[LiSa_MAXVOICES
], rampdown
[LiSa_MAXVOICES
];
3202 // allocate memory, length in samples
3203 inline int buffer_alloc(t_CKINT length
)
3205 mdata
= (SAMPLE
*)malloc(length
* sizeof(SAMPLE
));
3207 fprintf(stderr
, "LiSaBasic: unable to allocate memory!\n");
3212 maxvoices
= 10; // default; user can set
3214 rec_ramplen_inv
= 1.;
3218 for (t_CKINT i
=0; i
< LiSa_MAXVOICES
; i
++) {
3220 loop_end
[i
] = length
- 1;
3221 loop_end_rec
= length
;
3223 pindex
[i
] = rindex
= 0;
3224 play
[i
] = record
= bi
[i
] = false;
3225 looprec
= loopplay
[i
] = true;
3231 rampup
[i
] = rampdown
[i
] = false;
3232 rampup_len
[i
] = rampdown_len
[i
] = 0.;
3233 rampup_len_inv
[i
] = rampdown_len_inv
[i
] = 1.;
3240 // dump a sample into the buffer; retain existing sample, scaled by "coeff"
3241 inline void recordSamp(SAMPLE insample
)
3247 if(rindex
>= loop_end_rec
) rindex
= 0;
3248 tempsample
= coeff
* mdata
[rindex
] + insample
;
3249 //mdata[rindex] = coeff * mdata[rindex] + insample;
3252 if (rindex
< loop_end_rec
) {
3253 //mdata[rindex] = coeff * mdata[rindex] + insample;
3254 tempsample
= coeff
* mdata
[rindex
] + insample
;
3263 if(rindex
< rec_ramplen
) {
3264 tempsample
*= (rindex
* rec_ramplen_inv
);
3265 //fprintf(stderr, "ramping up %f\n", rindex * rec_ramplen_inv);
3266 } else if(rindex
> (loop_end_rec
- rec_ramplen
)) {
3267 tempsample
*= (loop_end_rec
- rindex
) * rec_ramplen_inv
;
3268 //fprintf(stderr, "ramping down %f\n", (loop_end_rec - rindex) * rec_ramplen_inv);
3270 mdata
[rindex
] = tempsample
;
3275 // grab a sample from the buffer, with linear interpolation (add prc's SINC interp later)
3276 // increment play index
3277 inline SAMPLE
getNextSamp(t_CKINT which
)
3280 if(loopplay
[which
]) {
3281 if(bi
[which
]) { // change direction if bidirectional mode
3282 if(pindex
[which
] > loop_end
[which
] || pindex
[which
] < loop_start
[which
]) {
3283 pindex
[which
] -= p_inc
[which
];
3284 p_inc
[which
] = -p_inc
[which
];
3287 if( loop_start
[which
] == loop_end
[which
] ) pindex
[which
] = loop_start
[which
]; //catch this condition to avoid infinite while loops
3289 while(pindex
[which
] > loop_end
[which
]) pindex
[which
] = loop_start
[which
] + (pindex
[which
] - loop_end
[which
]);
3290 while(pindex
[which
] < loop_start
[which
]) pindex
[which
] = loop_end
[which
] - (loop_start
[which
] - pindex
[which
]);
3293 } else if(pindex
[which
] > mdata_len
|| pindex
[which
] < 0) {
3295 //fprintf(stderr, "turning voice %d off!\n", which);
3300 t_CKINT whereTrunc
= (t_CKINT
) pindex
[which
];
3301 t_CKDOUBLE whereFrac
= pindex
[which
] - (t_CKDOUBLE
)whereTrunc
;
3302 t_CKINT whereNext
= whereTrunc
+ 1;
3304 if (loopplay
[which
]) {
3305 if((whereNext
) == loop_end
[which
]) {
3306 whereNext
= loop_start
[which
];
3309 if((whereTrunc
) == mdata_len
) {
3310 whereTrunc
= mdata_len
- 1;
3315 pindex
[which
] += p_inc
[which
];
3317 t_CKDOUBLE outsample
;
3318 outsample
= (t_CKDOUBLE
)mdata
[whereTrunc
] + (t_CKDOUBLE
)(mdata
[whereNext
] - mdata
[whereTrunc
]) * whereFrac
;
3322 outsample
*= rampctr
[which
]++ * rampup_len_inv
[which
]; //remove divide
3323 if(rampctr
[which
] >= rampup_len
[which
]) rampup
[which
] = false;
3325 else if(rampdown
[which
]) {
3326 outsample
*= (rampdown_len
[which
] - rampctr
[which
]++) * rampdown_len_inv
[which
];
3327 if(rampctr
[which
] >= rampdown_len
[which
]) {
3328 rampdown
[which
] = false;
3329 play
[which
] = false;
3333 outsample
*= voiceGain
[which
];
3335 return (SAMPLE
)outsample
;
3338 // grab a sample from the buffer, with linear interpolation (add prc's SINC interp later)
3339 // given a position within the buffer
3340 inline SAMPLE
getSamp(t_CKDOUBLE where
, t_CKINT which
)
3343 if(where
> loop_end
[which
]) where
= loop_end
[which
];
3344 if(where
< loop_start
[which
]) where
= loop_start
[which
];
3347 t_CKINT whereTrunc
= (t_CKINT
) where
;
3348 t_CKDOUBLE whereFrac
= where
- (t_CKDOUBLE
)whereTrunc
;
3349 t_CKINT whereNext
= whereTrunc
+ 1;
3351 if((whereNext
) == loop_end
[which
]) whereNext
= loop_start
[which
];
3353 t_CKDOUBLE outsample
;
3354 outsample
= (t_CKDOUBLE
)mdata
[whereTrunc
] + (t_CKDOUBLE
)(mdata
[whereNext
] - mdata
[whereTrunc
]) * whereFrac
;
3355 outsample
*= voiceGain
[which
];
3357 //add voiceGain ctl here; return (SAMPLE)vgain[which]*outsample;
3358 return (SAMPLE
)outsample
;
3362 inline void ramp_up(t_CKINT voicenum
, t_CKDUR uptime
)
3364 // fprintf(stderr, "ramping up voice %d", voicenum);
3366 rampup
[voicenum
] = true;
3367 play
[voicenum
] = true;
3368 rampup_len
[voicenum
] = (t_CKDOUBLE
)uptime
;
3369 if(rampup_len
[voicenum
] > 0.) rampup_len_inv
[voicenum
] = 1./rampup_len
[voicenum
];
3370 else rampup_len
[voicenum
] = 1.;
3372 // check to make sure we are not mid ramping down
3373 if(rampdown
[voicenum
]) {
3374 rampctr
[voicenum
] = rampup_len
[voicenum
] * (1. - rampctr
[voicenum
]/rampdown_len
[voicenum
]);
3375 rampdown
[voicenum
] = false;
3376 } else rampctr
[voicenum
] = 0;
3379 inline void ramp_down(t_CKINT voicenum
, t_CKDUR downtime
)
3381 rampdown
[voicenum
] = true;
3382 rampdown_len
[voicenum
] = (t_CKDOUBLE
)downtime
;
3383 if(rampdown_len
[voicenum
] > 0.) rampdown_len_inv
[voicenum
] = 1./rampdown_len
[voicenum
];
3384 else rampdown_len
[voicenum
] = 1.;
3386 // check to make sure we are not mid ramping up
3387 if(rampup
[voicenum
]) {
3388 rampctr
[voicenum
] = rampdown_len
[voicenum
] * (1. - rampctr
[voicenum
]/rampup_len
[voicenum
]);
3389 rampup
[voicenum
] = false;
3390 } else rampctr
[voicenum
] = 0;
3393 inline void set_rec_ramplen(t_CKDUR newlen
)
3395 rec_ramplen
= (t_CKDOUBLE
)newlen
;
3396 if(rec_ramplen
> 0.) rec_ramplen_inv
= 1./rec_ramplen
;
3397 else rec_ramplen_inv
= 1.;
3398 //fprintf ( stderr, "rec_ramplen = %f, inv = %f \n", rec_ramplen, rec_ramplen_inv );
3402 // may want to make multichannel version,
3403 // want to be able to do the following:
3405 // l.pan(voice, panval)
3406 //for simple stereo panning of a particular voice, and...
3407 // l.channelGain(voice, channel, gain)
3408 //to set the gain for a particular voice going to a particular channel; good for >2 voices (like 6 channels!)
3409 inline SAMPLE
tick_multi( SAMPLE in
)
3411 if(!mdata
) return (SAMPLE
) 0.;
3415 SAMPLE tempsample
= 0.;
3418 for (t_CKINT i
=0; i
<maxvoices
; i
++) {
3419 if(play
[i
]) tempsample
+= getNextSamp(i
);
3421 } else if(track
==1) {
3423 for (t_CKINT i
=0; i
<maxvoices
; i
++) {
3424 if(play
[i
]) tempsample
+= getSamp((t_CKDOUBLE
)in
* (loop_end
[i
] - loop_start
[i
]) + loop_start
[i
], i
);
3426 } else if(track
==2 && play
[0]) {
3427 if(in
<0.) in
= -in
; //only use voice 0 when tracking with durs.
3428 tempsample
= getSamp( (t_CKDOUBLE
)in
, 0 );
3434 inline void clear_buf()
3436 for (t_CKINT i
= 0; i
< mdata_len
; i
++)
3440 inline t_CKINT
get_free_voice()
3442 t_CKINT voicenumber
= 0;
3443 while(play
[voicenumber
] && voicenumber
< maxvoices
) {
3446 if(voicenumber
== maxvoices
) voicenumber
= -1;
3450 //stick sample in record buffer
3451 inline void pokeSample( SAMPLE insample
, t_CKINT index
) {
3453 if ( index
> mdata_len
|| index
< 0 ) {
3455 fprintf(stderr
, "LiSa: trying to put sample out of buffer range; ignoring");
3456 } else mdata
[index
] = insample
;
3460 //grab sample directly from record buffer, with linear interpolation
3461 inline SAMPLE
grabSample ( t_CKDOUBLE where
) {
3463 if ( where
> mdata_len
|| where
< 0 ) {
3465 fprintf(stderr
, "LiSa: trying to grab sample out of buffer range; ignoring");
3470 t_CKINT whereTrunc
= (t_CKINT
) where
;
3471 t_CKDOUBLE whereFrac
= where
- (t_CKDOUBLE
)whereTrunc
;
3472 t_CKINT whereNext
= whereTrunc
+ 1;
3474 if((whereNext
) == mdata_len
) whereNext
= 0;
3476 t_CKDOUBLE outsample
;
3477 outsample
= (t_CKDOUBLE
)mdata
[whereTrunc
] + (t_CKDOUBLE
)(mdata
[whereNext
] - mdata
[whereTrunc
]) * whereFrac
;
3479 //add voiceGain ctl here; return (SAMPLE)vgain[which]*outsample;
3480 return (SAMPLE
)outsample
;
3490 //++++++++++++++++++++++++++++++++++++++++
3493 //++++++++++++++++++++++++++++++++++++++++
3496 //++++++++++++++++++++++++++++++++++++++++
3501 //-----------------------------------------------------------------------------
3502 // name: LiSaMulti_ctor()
3503 // desc: CTOR function ...
3504 //-----------------------------------------------------------------------------
3505 CK_DLL_CTOR( LiSaMulti_ctor
)
3508 LiSaMulti_data
* f
= new LiSaMulti_data
;
3509 memset( f
, 0, sizeof(LiSaMulti_data
) );
3510 OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
) = (t_CKUINT
)f
;
3515 //-----------------------------------------------------------------------------
3516 // name: LiSaMulti_dtor()
3517 // desc: DTOR function ...
3518 //-----------------------------------------------------------------------------
3519 CK_DLL_DTOR( LiSaMulti_dtor
)
3522 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3526 OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
) = 0;
3530 //-----------------------------------------------------------------------------
3531 // name: LiSaMulti_tick()
3532 // desc: TICK function ...
3533 //-----------------------------------------------------------------------------
3534 CK_DLL_TICK( LiSaMulti_tick
)
3536 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3537 *out
= d
->tick_multi( in
);
3542 //-----------------------------------------------------------------------------
3543 // name: LiSaMulti_size()
3544 // desc: set size of buffer allocation
3545 //-----------------------------------------------------------------------------
3546 CK_DLL_CTRL( LiSaMulti_size
)
3548 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3549 t_CKDUR buflen
= GET_NEXT_DUR(ARGS
);
3550 if (buflen
> LiSa_MAXBUFSIZE
) {
3551 fprintf(stderr
, "buffer size request too large, resizing\n");
3552 buflen
= LiSa_MAXBUFSIZE
;
3554 d
->buffer_alloc((t_CKINT
)buflen
);
3556 RETURN
->v_dur
= (t_CKDUR
)buflen
;
3559 CK_DLL_CGET( LiSaMulti_cget_size
)
3561 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3563 RETURN
->v_dur
= (t_CKDUR
)d
->mdata_len
;
3567 //-----------------------------------------------------------------------------
3568 // name: LiSaMulti_start_record()
3569 // desc: CTRL function ...
3570 //-----------------------------------------------------------------------------
3571 CK_DLL_CTRL( LiSaMulti_start_record
)
3573 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3574 d
->record
= GET_NEXT_INT(ARGS
);
3576 RETURN
->v_int
= (t_CKINT
)d
->record
;
3580 //-----------------------------------------------------------------------------
3581 // name: LiSaMulti_start_play()
3582 // desc: CTRL function
3583 //-----------------------------------------------------------------------------
3584 CK_DLL_CTRL( LiSaMulti_start_play
)
3586 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3587 t_CKINT which
= GET_NEXT_INT(ARGS
);
3588 d
->play
[which
] = GET_NEXT_INT(ARGS
);
3589 //fprintf(stderr, "voice %d playing = %d\n", which, d->play[which]);
3591 //turn off ramping toggles
3592 d
->rampdown
[which
] = false;
3593 d
->rampup
[which
] = false;
3595 RETURN
->v_int
= (t_CKINT
)d
->play
[which
];
3599 //-----------------------------------------------------------------------------
3600 // name: LiSaMulti_start_play()
3601 // desc: CTRL function
3602 //-----------------------------------------------------------------------------
3603 CK_DLL_CTRL( LiSaMulti_start_play0
)
3606 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3607 d
->play
[0] = GET_NEXT_INT(ARGS
);
3608 //fprintf(stderr, "voice %d playing = %d\n", which, d->play[which]);
3610 //turn off ramping toggles
3611 d
->rampdown
[0] = false;
3612 d
->rampup
[0] = false;
3614 RETURN
->v_int
= (t_CKINT
)d
->play
[0];
3619 //-----------------------------------------------------------------------------
3620 // name: LiSaMulti_ctrl_rate()
3621 // desc: CTRL function
3622 //-----------------------------------------------------------------------------
3623 CK_DLL_CTRL( LiSaMulti_ctrl_rate
)
3625 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3626 t_CKINT which
= GET_NEXT_INT(ARGS
);
3627 d
->p_inc
[which
] = (t_CKDOUBLE
)GET_NEXT_FLOAT(ARGS
);
3628 //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]);
3630 RETURN
->v_float
= d
->p_inc
[which
];
3634 CK_DLL_CTRL( LiSaMulti_ctrl_rate0
)
3636 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3637 d
->p_inc
[0] = (t_CKDOUBLE
)GET_NEXT_FLOAT(ARGS
);
3638 //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]);
3640 RETURN
->v_float
= d
->p_inc
[0];
3643 //-----------------------------------------------------------------------------
3644 // name: LiSaMulti_cget_rate()
3645 // desc: CTRL function
3646 //-----------------------------------------------------------------------------
3647 CK_DLL_CTRL( LiSaMulti_cget_rate
)
3649 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3650 t_CKINT which
= GET_NEXT_INT(ARGS
);
3651 //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]);
3653 RETURN
->v_float
= d
->p_inc
[which
];
3657 CK_DLL_CTRL( LiSaMulti_cget_rate0
)
3659 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3660 //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]);
3662 RETURN
->v_float
= d
->p_inc
[0];
3665 //-----------------------------------------------------------------------------
3666 // name: LiSaMulti_ctrl_pindex()
3667 // desc: CTRL function
3668 //-----------------------------------------------------------------------------
3669 CK_DLL_CTRL( LiSaMulti_ctrl_pindex
)
3671 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3672 t_CKINT which
= GET_NEXT_INT(ARGS
);
3673 d
->pindex
[which
] = (t_CKDOUBLE
)GET_NEXT_DUR(ARGS
);
3675 RETURN
->v_dur
= (t_CKDUR
)d
->pindex
[which
];
3679 CK_DLL_CTRL( LiSaMulti_ctrl_pindex0
)
3681 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3682 d
->pindex
[0] = (t_CKDOUBLE
)GET_NEXT_DUR(ARGS
);
3684 RETURN
->v_dur
= (t_CKDUR
)d
->pindex
[0];
3688 //-----------------------------------------------------------------------------
3689 // name: LiSaMulti_cget_pindex()
3690 // desc: CGET function
3691 //-----------------------------------------------------------------------------
3692 CK_DLL_CGET( LiSaMulti_cget_pindex
)
3694 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3695 t_CKINT which
= GET_NEXT_INT(ARGS
);
3698 RETURN
->v_dur
= (t_CKDUR
)d
->pindex
[which
];
3702 CK_DLL_CGET( LiSaMulti_cget_pindex0
)
3704 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3707 RETURN
->v_dur
= (t_CKDUR
)d
->pindex
[0];
3711 //-----------------------------------------------------------------------------
3712 // name: LiSaMulti_ctrl_pindex()
3713 // desc: CTRL function
3714 //-----------------------------------------------------------------------------
3715 CK_DLL_CTRL( LiSaMulti_ctrl_rindex
)
3717 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3718 d
->rindex
= /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3720 RETURN
->v_dur
= (t_CKDUR
)d
->rindex
;
3724 //-----------------------------------------------------------------------------
3725 // name: LiSaMulti_cget_pindex()
3726 // desc: CGET function
3727 //-----------------------------------------------------------------------------
3728 CK_DLL_CGET( LiSaMulti_cget_rindex
)
3730 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3733 RETURN
->v_dur
= (t_CKDUR
)d
->rindex
;
3737 //-----------------------------------------------------------------------------
3738 // name: LiSaMulti_ctrl_lstart()
3739 // desc: CTRL function
3740 //-----------------------------------------------------------------------------
3741 CK_DLL_CTRL( LiSaMulti_ctrl_lstart
)
3743 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3744 t_CKINT which
= GET_NEXT_INT(ARGS
);
3745 d
->loop_start
[which
] = /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3747 if (d
->loop_start
[which
] < 0) d
->loop_start
[which
] = 0;
3749 RETURN
->v_dur
= (t_CKDUR
)d
->loop_start
[which
];
3753 CK_DLL_CTRL( LiSaMulti_ctrl_lstart0
)
3755 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3756 d
->loop_start
[0] = /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3758 if (d
->loop_start
[0] < 0) d
->loop_start
[0] = 0;
3760 RETURN
->v_dur
= (t_CKDUR
)d
->loop_start
[0];
3764 //-----------------------------------------------------------------------------
3765 // name: LiSaMulti_cget_lstart()
3766 // desc: CGET function
3767 //-----------------------------------------------------------------------------
3768 CK_DLL_CGET( LiSaMulti_cget_lstart
)
3770 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3772 t_CKINT which
= GET_NEXT_INT(ARGS
);
3774 RETURN
->v_dur
= (t_CKDUR
)d
->loop_start
[which
];
3778 CK_DLL_CGET( LiSaMulti_cget_lstart0
)
3780 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3783 RETURN
->v_dur
= (t_CKDUR
)d
->loop_start
[0];
3787 //-----------------------------------------------------------------------------
3788 // name: LiSaMulti_ctrl_lend()
3789 // desc: CTRL function
3790 //-----------------------------------------------------------------------------
3791 CK_DLL_CTRL( LiSaMulti_ctrl_lend
)
3793 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3794 t_CKINT which
= GET_NEXT_INT(ARGS
);
3795 d
->loop_end
[which
] = /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3797 //check to make sure loop_end is not too large
3798 if (d
->loop_end
[which
] >= d
->mdata_len
) d
->loop_end
[which
] = d
->mdata_len
- 1;
3800 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end
[which
];
3804 CK_DLL_CTRL( LiSaMulti_ctrl_lend0
)
3806 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3807 d
->loop_end
[0] = /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3809 //check to make sure loop_end is not too large
3810 if (d
->loop_end
[0] >= d
->mdata_len
) d
->loop_end
[0] = d
->mdata_len
- 1;
3812 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end
[0];
3816 //-----------------------------------------------------------------------------
3817 // name: LiSaMulti_cget_lend()
3818 // desc: CGET function
3819 //-----------------------------------------------------------------------------
3820 CK_DLL_CGET( LiSaMulti_cget_lend
)
3822 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3823 t_CKINT which
= GET_NEXT_INT(ARGS
);
3826 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end
[which
];
3830 CK_DLL_CGET( LiSaMulti_cget_lend0
)
3832 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3835 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end
[0];
3839 //-----------------------------------------------------------------------------
3840 // name: LiSaMulti_ctrl_loop()
3841 // desc: CTRL function
3842 //-----------------------------------------------------------------------------
3843 CK_DLL_CTRL( LiSaMulti_ctrl_loop
)
3845 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3846 t_CKINT which
= GET_NEXT_INT(ARGS
);
3847 d
->loopplay
[which
] = (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3851 CK_DLL_CTRL( LiSaMulti_ctrl_loop0
)
3853 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3854 d
->loopplay
[0] = (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3856 RETURN
->v_int
= (t_CKINT
)d
->loopplay
[0];
3860 //-----------------------------------------------------------------------------
3861 // name: LiSaMulti_cget_loop()
3862 // desc: CGET function
3863 //-----------------------------------------------------------------------------
3864 CK_DLL_CGET( LiSaMulti_cget_loop
)
3866 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3867 t_CKINT which
= GET_NEXT_INT(ARGS
);
3870 RETURN
->v_int
= (t_CKINT
)d
->loopplay
[which
];
3874 CK_DLL_CGET( LiSaMulti_cget_loop0
)
3876 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3879 RETURN
->v_int
= (t_CKINT
)d
->loopplay
[0];
3883 //-----------------------------------------------------------------------------
3884 // name: LiSaMulti_ctrl_bi()
3885 // desc: CTRL function
3886 //-----------------------------------------------------------------------------
3887 CK_DLL_CTRL( LiSaMulti_ctrl_bi
)
3889 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3890 t_CKINT which
= GET_NEXT_INT(ARGS
);
3891 d
->bi
[which
] = (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3893 RETURN
->v_int
= (t_CKINT
)d
->bi
[which
];
3897 CK_DLL_CTRL( LiSaMulti_ctrl_bi0
)
3899 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3900 d
->bi
[0] = (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3902 RETURN
->v_int
= (t_CKINT
)d
->bi
[0];
3906 //-----------------------------------------------------------------------------
3907 // name: LiSaMulti_cget_bi()
3908 // desc: CGET function
3909 //-----------------------------------------------------------------------------
3910 CK_DLL_CGET( LiSaMulti_cget_bi
)
3912 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3913 t_CKINT which
= GET_NEXT_INT(ARGS
);
3916 RETURN
->v_int
= (t_CKINT
)d
->bi
[which
];
3920 CK_DLL_CGET( LiSaMulti_cget_bi0
)
3922 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3925 RETURN
->v_int
= (t_CKINT
)d
->bi
[0];
3929 //-----------------------------------------------------------------------------
3930 // name: LiSaMulti_ctrl_loop_end_rec()
3931 // desc: CTRL function
3932 //-----------------------------------------------------------------------------
3933 CK_DLL_CTRL( LiSaMulti_ctrl_loop_end_rec
)
3935 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3936 d
->loop_end_rec
= /* gewang-> */(t_CKINT
)GET_NEXT_DUR(ARGS
);
3938 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end_rec
;
3942 //-----------------------------------------------------------------------------
3943 // name: LiSaMulti_cget_loop_end_rec()
3944 // desc: CGET function
3945 //-----------------------------------------------------------------------------
3946 CK_DLL_CGET( LiSaMulti_cget_loop_end_rec
)
3948 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3951 RETURN
->v_dur
= (t_CKDUR
)d
->loop_end_rec
;
3955 //-----------------------------------------------------------------------------
3956 // name: LiSaMulti_ctrl_loop_rec()
3957 // desc: CTRL function
3958 //-----------------------------------------------------------------------------
3959 CK_DLL_CTRL( LiSaMulti_ctrl_loop_rec
)
3961 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3962 d
->looprec
= (t_CKBOOL
)GET_NEXT_INT(ARGS
);
3964 RETURN
->v_int
= (t_CKINT
)d
->looprec
;
3968 //-----------------------------------------------------------------------------
3969 // name: LiSaMulti_cget_loop_rec()
3970 // desc: CGET function
3971 //-----------------------------------------------------------------------------
3972 CK_DLL_CGET( LiSaMulti_cget_loop_rec
)
3974 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3977 RETURN
->v_int
= (t_CKINT
)d
->looprec
;
3980 //-----------------------------------------------------------------------------
3981 // name: LiSaMulti_ctrl_sample(); put a sample directly into record buffer
3982 // desc: CTRL function
3983 //-----------------------------------------------------------------------------
3984 CK_DLL_CTRL( LiSaMulti_ctrl_sample
)
3986 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
3987 SAMPLE sample_in
= (SAMPLE
)GET_NEXT_FLOAT(ARGS
);
3988 int index_in
= (t_CKINT
)GET_NEXT_DUR(ARGS
);
3990 d
->pokeSample( sample_in
, index_in
);
3992 RETURN
->v_float
= (t_CKFLOAT
)sample_in
; //pass input through
3995 //-----------------------------------------------------------------------------
3996 // name: LiSaMulti_cget_sample(); grab a sample from the record buffer
3997 // desc: CGET function
3998 //-----------------------------------------------------------------------------
3999 CK_DLL_CGET( LiSaMulti_cget_sample
)
4001 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4002 double index_in
= (t_CKDOUBLE
)GET_NEXT_DUR(ARGS
);
4004 RETURN
->v_float
= (t_CKFLOAT
)d
->grabSample( index_in
); //change this to getSamp for interpolation
4008 //-----------------------------------------------------------------------------
4009 // name: LiSaMulti_ctrl_voicegain()
4010 // desc: CTRL function
4011 //-----------------------------------------------------------------------------
4012 CK_DLL_CTRL( LiSaMulti_ctrl_voicegain
)
4014 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4015 t_CKINT which
= GET_NEXT_INT(ARGS
);
4016 d
->voiceGain
[which
] = (t_CKDOUBLE
)GET_NEXT_FLOAT(ARGS
);
4018 RETURN
->v_float
= (t_CKFLOAT
)d
->coeff
;
4022 //-----------------------------------------------------------------------------
4023 // name: LiSaMulti_cget_voicegain()
4024 // desc: CGET function
4025 //-----------------------------------------------------------------------------
4026 CK_DLL_CGET( LiSaMulti_cget_voicegain
)
4028 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4029 t_CKINT which
= GET_NEXT_INT(ARGS
);
4032 RETURN
->v_float
= (t_CKFLOAT
)d
->voiceGain
[which
];
4036 //-----------------------------------------------------------------------------
4037 // name: LiSaMulti_ctrl_coeff()
4038 // desc: CTRL function
4039 //-----------------------------------------------------------------------------
4040 CK_DLL_CTRL( LiSaMulti_ctrl_coeff
)
4042 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4043 d
->coeff
= (t_CKDOUBLE
)GET_NEXT_FLOAT(ARGS
);
4045 RETURN
->v_float
= (t_CKFLOAT
)d
->coeff
;
4048 //-----------------------------------------------------------------------------
4049 // name: LiSaMulti_cget_coeff()
4050 // desc: CGET function
4051 //-----------------------------------------------------------------------------
4052 CK_DLL_CGET( LiSaMulti_cget_coeff
)
4054 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4057 RETURN
->v_float
= (t_CKFLOAT
)d
->coeff
;
4061 //-----------------------------------------------------------------------------
4062 // name: LiSaMulti_ctrl_clear()
4063 // desc: CTRL function
4064 //-----------------------------------------------------------------------------
4065 CK_DLL_CTRL( LiSaMulti_ctrl_clear
)
4067 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4073 //-----------------------------------------------------------------------------
4074 // name: LiSaMulti_cget_voice()
4075 // desc: CGET function
4076 //-----------------------------------------------------------------------------
4077 CK_DLL_CGET( LiSaMulti_cget_voice
)
4079 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4082 RETURN
->v_int
= (t_CKINT
)d
->get_free_voice();
4087 //-----------------------------------------------------------------------------
4088 // name: LiSaMulti_ctrl_rampup()
4089 // desc: CTRL function
4090 //-----------------------------------------------------------------------------
4091 CK_DLL_CTRL( LiSaMulti_ctrl_rampup
)
4093 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4094 t_CKINT voice
= GET_NEXT_INT(ARGS
);
4095 t_CKDUR len
= GET_NEXT_DUR(ARGS
);
4097 d
->ramp_up(voice
, len
);
4099 RETURN
->v_dur
= (t_CKDUR
)len
;
4103 CK_DLL_CTRL( LiSaMulti_ctrl_rampup0
)
4105 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4106 t_CKDUR len
= GET_NEXT_DUR(ARGS
);
4110 RETURN
->v_dur
= (t_CKDUR
)len
;
4114 //-----------------------------------------------------------------------------
4115 // name: LiSaMulti_ctrl_rampdown()
4116 // desc: CTRL function
4117 //-----------------------------------------------------------------------------
4118 CK_DLL_CTRL( LiSaMulti_ctrl_rampdown
)
4120 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4121 t_CKINT voice
= GET_NEXT_INT(ARGS
);
4122 t_CKDUR len
= GET_NEXT_DUR(ARGS
);
4124 d
->ramp_down(voice
, len
);
4126 RETURN
->v_dur
= (t_CKDUR
)len
;
4130 CK_DLL_CTRL( LiSaMulti_ctrl_rampdown0
)
4132 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4133 t_CKDUR len
= GET_NEXT_DUR(ARGS
);
4135 d
->ramp_down(0, len
);
4137 RETURN
->v_dur
= (t_CKDUR
)len
;
4141 //-----------------------------------------------------------------------------
4142 // name: LiSaMulti_ctrl_rec_ramplen()
4143 // desc: CTRL function
4144 //-----------------------------------------------------------------------------
4145 CK_DLL_CTRL( LiSaMulti_ctrl_rec_ramplen
)
4147 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4148 t_CKDUR newramplen
= GET_NEXT_DUR(ARGS
);
4149 d
->set_rec_ramplen(newramplen
);
4151 RETURN
->v_dur
= (t_CKDUR
)newramplen
;
4155 //-----------------------------------------------------------------------------
4156 // name: LiSaMulti_ctrl_maxvoices()
4157 // desc: CTRL function
4158 //-----------------------------------------------------------------------------
4159 CK_DLL_CTRL( LiSaMulti_ctrl_maxvoices
)
4161 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4162 d
->maxvoices
= GET_NEXT_INT(ARGS
);
4163 if( d
->maxvoices
> LiSa_MAXVOICES
) {
4164 d
->maxvoices
= LiSa_MAXVOICES
;
4165 fprintf(stderr
, "LiSa: MAXVOICES limited to %d.\n", LiSa_MAXVOICES
);
4167 RETURN
->v_int
= d
->maxvoices
;
4171 //-----------------------------------------------------------------------------
4172 // name: LiSaMulti_cget_maxvoices()
4173 // desc: CGET function
4174 //-----------------------------------------------------------------------------
4175 CK_DLL_CGET( LiSaMulti_cget_maxvoices
)
4177 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4180 RETURN
->v_int
= d
->maxvoices
;
4184 //-----------------------------------------------------------------------------
4185 // name: LiSaMulti_cget_samp()
4186 // desc: CGET function
4187 //-----------------------------------------------------------------------------
4188 CK_DLL_CGET( LiSaMulti_cget_value
)
4190 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4191 t_CKINT voice
= GET_NEXT_INT(ARGS
);
4192 t_CKDOUBLE where
= (t_CKDOUBLE
) GET_NEXT_DUR(ARGS
);
4195 RETURN
->v_dur
= (t_CKDUR
)d
->getSamp(where
, voice
);
4199 CK_DLL_CGET( LiSaMulti_cget_value0
)
4201 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4203 t_CKDOUBLE where
= (t_CKDOUBLE
) GET_NEXT_DUR(ARGS
);
4205 RETURN
->v_dur
= (t_CKDUR
)d
->getSamp(where
, 0);
4209 //-----------------------------------------------------------------------------
4210 // name: LiSaMulti_ctrl_track()
4211 // desc: CTRL function
4212 //-----------------------------------------------------------------------------
4213 CK_DLL_CTRL( LiSaMulti_ctrl_track
)
4215 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4216 d
->track
= (t_CKINT
)GET_NEXT_INT(ARGS
);
4218 RETURN
->v_int
= d
->track
;
4222 //-----------------------------------------------------------------------------
4223 // name: LiSaMulti_cget_sync()
4224 // desc: CGET function
4225 //-----------------------------------------------------------------------------
4226 CK_DLL_CGET( LiSaMulti_cget_track
)
4228 LiSaMulti_data
* d
= (LiSaMulti_data
*)OBJ_MEMBER_UINT(SELF
, LiSaMulti_offset_data
);
4231 RETURN
->v_int
= d
->track
;
4235 //-----------------------------------------------------------------------------
4236 // name: LiSaMulti_pmsg()
4237 // desc: PMSG function ...
4238 //-----------------------------------------------------------------------------
4239 CK_DLL_PMSG(LiSaMulti_pmsg
)