1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
27 // desc: import library for Synthesis ToolKit (STK) - Perry Cook + Gary Scavone
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 //-----------------------------------------------------------------------------
38 #define MY_FLOAT double
42 /***************************************************/
46 Nearly all STK classes inherit from this class.
47 The global sample rate and rawwave path variables
48 can be queried and modified via Stk. In addition,
49 this class provides error handling and
50 byte-swapping functions.
52 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
54 /***************************************************/
62 // Most data in STK is passed and calculated with the
63 // following user-definable floating-point type. You
64 // can change this to "float" if you prefer or perhaps
65 // a "long double" in the future.
67 //XXX sample is already defined in chuck_def.h!!!
69 typedef SAMPLE MY_FLOAT
;
71 // The "MY_FLOAT" type will be deprecated in STK
72 // versions higher than 4.1.2 and replaced with the variable
74 //typedef double StkFloat;
75 //#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
76 // #pragma deprecated(MY_FLOAT)
78 // typedef StkFloat MY_FLOAT __attribute__ ((deprecated));
81 //! STK error handling class.
83 This is a fairly abstract exception handling class. There could
84 be sub-classes to take care of more specific error conditions ... or
99 PROCESS_SOCKET_IPADDR
,
105 public: // SWAP formerly protected
111 StkError(const char *p
, TYPE tipe
= StkError::UNSPECIFIED
);
114 virtual ~StkError(void);
116 //! Prints "thrown" error message to stdout.
117 virtual void printMessage(void);
119 //! Returns the "thrown" error message TYPE.
120 virtual const TYPE
& getType(void) { return type
; }
122 //! Returns the "thrown" error message string.
123 virtual const char *getMessage(void) const { return message
; }
131 typedef unsigned long STK_FORMAT
;
132 static const STK_FORMAT STK_SINT8
; /*!< -128 to +127 */
133 static const STK_FORMAT STK_SINT16
; /*!< -32768 to +32767 */
134 static const STK_FORMAT STK_SINT32
; /*!< -2147483648 to +2147483647. */
135 static const STK_FORMAT MY_FLOAT32
; /*!< Normalized between plus/minus 1.0. */
136 static const STK_FORMAT MY_FLOAT64
; /*!< Normalized between plus/minus 1.0. */
138 //! Static method which returns the current STK sample rate.
139 static MY_FLOAT
sampleRate(void);
141 //! Static method which sets the STK sample rate.
143 The sample rate set using this method is queried by all STK
144 classes which depend on its value. It is initialized to the
145 default SRATE set in Stk.h. Many STK classes use the sample rate
146 during instantiation. Therefore, if you wish to use a rate which
147 is different from the default rate, it is imperative that it be
148 set \e BEFORE STK objects are instantiated.
150 static void setSampleRate(MY_FLOAT newRate
);
152 //! Static method which returns the current rawwave path.
153 static std::string
rawwavePath(void);
155 //! Static method which sets the STK rawwave path.
156 static void setRawwavePath(std::string newPath
);
158 //! Static method which byte-swaps a 16-bit data type.
159 static void swap16(unsigned char *ptr
);
161 //! Static method which byte-swaps a 32-bit data type.
162 static void swap32(unsigned char *ptr
);
164 //! Static method which byte-swaps a 64-bit data type.
165 static void swap64(unsigned char *ptr
);
167 //! Static cross-platform method to sleep for a number of milliseconds.
168 static void sleep(unsigned long milliseconds
);
170 public: // SWAP formerly private
171 static MY_FLOAT srate
;
172 static std::string rawwavepath
;
174 public: // SWAP formerly protected
176 //! Default constructor.
179 //! Class destructor.
182 //! Function for error reporting and handling.
183 static void handleError( const char *message
, StkError::TYPE type
);
187 // Here are a few other useful typedefs.
188 typedef signed short SINT16
;
189 typedef signed int SINT32
;
190 typedef float FLOAT32
;
191 typedef double FLOAT64
;
197 // The default sampling rate.
198 #define SRATE (MY_FLOAT) 44100.0
200 // The default real-time audio input and output buffer size. If
201 // clicks are occuring in the input and/or output sound stream, a
202 // larger buffer size may help. Larger buffer sizes, however, produce
204 #define RT_BUFFER_SIZE 512
206 // The default rawwave path value is set with the preprocessor
207 // definition RAWWAVE_PATH. This can be specified as an argument to
208 // the configure script, in an integrated development environment, or
209 // below. The global STK rawwave path variable can be dynamically set
210 // with the Stk::setRawwavePath() function. This value is
211 // concatenated to the beginning of all references to rawwave files in
212 // the various STK core classes (ex. Clarinet.cpp). If you wish to
213 // move the rawwaves directory to a different location in your file
214 // system, you will need to set this path definition appropriately.
215 #if !defined(RAWWAVE_PATH)
216 #define RAWWAVE_PATH "../../rawwaves/"
219 #define PI (MY_FLOAT) 3.14159265359
220 #define TWO_PI (MY_FLOAT) (2 * PI)
222 #define ONE_OVER_128 (MY_FLOAT) 0.0078125
224 #if defined(__WINDOWS_PTHREAD__)
225 #define __OS_WINDOWS_CYGWIN__
226 #define __STK_REALTIME__
227 #elif defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
228 #define __OS_WINDOWS__
229 #define __STK_REALTIME__
230 #elif defined(__LINUX_OSS__) || defined(__LINUX_ALSA__) || defined(__LINUX_JACK__)
232 #define __STK_REALTIME__
233 #elif defined(__IRIX_AL__)
235 #define __STK_REALTIME__
236 #elif defined(__MACOSX_CORE__)
237 #define __OS_MACOSX__
238 #define __STK_REALTIME__
241 //#define _STK_DEBUG_
246 //------------------------------------------------------------------------------
249 //------------------------------------------------------------------------------
250 union what
{ long x
; char y
[sizeof(long)]; };
251 t_CKBOOL little_endian
= FALSE
;
253 //-----------------------------------------------------------------------------
256 //-----------------------------------------------------------------------------
257 DLL_QUERY
stk_query( Chuck_DL_Query
* QUERY
)
260 Stk::setSampleRate( QUERY
->srate
);
263 little_endian
= (t_CKBOOL
)w
.y
[0];
267 //! \section stk - instruments
270 QUERY
->ugen_add( QUERY
, "BandedWG", NULL
);
271 QUERY
->ugen_func( QUERY
, BandedWG_ctor
, BandedWG_dtor
, BandedWG_tick
, BandedWG_pmsg
);
272 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! noteOn
273 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! noteOff
274 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_pluck
, NULL
, "float", "pluck" ); //! pluck waveguide
275 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_startBowing
, NULL
, "float", "startBowing" ); //! pluck waveguide
276 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_stopBowing
, NULL
, "float", "stopBowing" ); //! pluck waveguide
277 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_freq
, BandedWG_cget_freq
, "float", "freq" ); //! strike Position
278 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_bowRate
, BandedWG_cget_bowRate
, "float", "bowRate" ); //! strike Position
279 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_bowPressure
, BandedWG_cget_bowPressure
, "float", "bowPressure" ); //! strike Position
280 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_preset
, BandedWG_cget_preset
, "int", "preset" ); //! strike Position
281 QUERY
->ugen_ctrl( QUERY
, BandedWG_ctrl_strikePosition
, BandedWG_cget_strikePosition
, "float", "strikePosition" ); //! strike Position
284 QUERY
->ugen_add( QUERY
, "BlowBotl", NULL
);
285 QUERY
->ugen_func( QUERY
, BlowBotl_ctor
, BlowBotl_dtor
, BlowBotl_tick
, BlowBotl_pmsg
);
286 QUERY
->ugen_ctrl( QUERY
, BlowBotl_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! note on
287 QUERY
->ugen_ctrl( QUERY
, BlowBotl_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! note on
288 QUERY
->ugen_ctrl( QUERY
, BlowBotl_ctrl_startBlowing
, NULL
, "float", "startBlowing" ); //! note on
289 QUERY
->ugen_ctrl( QUERY
, BlowBotl_ctrl_stopBlowing
, NULL
, "float", "stopBlowing" ); //! note on
290 QUERY
->ugen_ctrl( QUERY
, BlowBotl_ctrl_freq
, BlowBotl_cget_freq
, "float", "freq" ); //! frequency
291 QUERY
->ugen_ctrl( QUERY
, BlowBotl_ctrl_rate
, BlowBotl_cget_rate
, "float", "rate" ); //! frequency
294 QUERY
->ugen_add( QUERY
, "BlowHole", NULL
);
295 QUERY
->ugen_func( QUERY
, BlowHole_ctor
, BlowHole_dtor
, BlowHole_tick
, BlowHole_pmsg
);
296 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! note on
297 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! note on
298 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_startBlowing
, NULL
, "float", "startBlowing" ); //! note on
299 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_stopBlowing
, NULL
, "float", "stopBlowing" ); //! note on
300 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_freq
, BlowHole_cget_freq
, "float", "freq" ); //! frequency
301 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_vent
, BlowHole_cget_vent
, "float", "vent" ); //! vent frequency
302 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_tonehole
, BlowHole_cget_tonehole
, "float", "tonehole" ); //! tonehole size
303 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_reed
, BlowHole_cget_reed
, "float", "reed" ); //! reed stiffness
304 QUERY
->ugen_ctrl( QUERY
, BlowHole_ctrl_rate
, BlowHole_cget_rate
, "float", "rate" ); //! rate of change
307 QUERY
->ugen_add( QUERY
, "Bowed", NULL
);
308 QUERY
->ugen_func( QUERY
, Bowed_ctor
, Bowed_dtor
, Bowed_tick
, Bowed_pmsg
);
309 QUERY
->ugen_ctrl( QUERY
, Bowed_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! note on
310 QUERY
->ugen_ctrl( QUERY
, Bowed_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! note off
311 QUERY
->ugen_ctrl( QUERY
, Bowed_ctrl_startBowing
, NULL
, "float", "startBowing" ); //! begin bowing instrument
312 QUERY
->ugen_ctrl( QUERY
, Bowed_ctrl_stopBowing
, NULL
, "float", "stopBowing" ); //! stop bowing
313 QUERY
->ugen_ctrl( QUERY
, Bowed_ctrl_freq
, Bowed_cget_freq
, "float", "freq" ); //!
314 QUERY
->ugen_ctrl( QUERY
, Bowed_ctrl_rate
, Bowed_cget_rate
, "float", "rate" ); //!
315 QUERY
->ugen_ctrl( QUERY
, Bowed_ctrl_vibrato
, Bowed_cget_vibrato
, "float", "vibrato" ); //!
318 QUERY
->ugen_add( QUERY
, "Brass", NULL
);
319 QUERY
->ugen_func( QUERY
, Brass_ctor
, Brass_dtor
, Brass_tick
, Brass_pmsg
);
320 QUERY
->ugen_ctrl( QUERY
, Brass_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! note on
321 QUERY
->ugen_ctrl( QUERY
, Brass_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! note on
322 QUERY
->ugen_ctrl( QUERY
, Brass_ctrl_clear
, NULL
, "float", "clear" ); //! clear instrument
323 QUERY
->ugen_ctrl( QUERY
, Brass_ctrl_startBlowing
, NULL
, "float", "startBlowing" ); //! note on
324 QUERY
->ugen_ctrl( QUERY
, Brass_ctrl_stopBlowing
, NULL
, "float", "stopBlowing" ); //! note on
325 QUERY
->ugen_ctrl( QUERY
, Brass_ctrl_freq
, Brass_cget_freq
, "float", "freq" ); //! frequency
326 QUERY
->ugen_ctrl( QUERY
, Brass_ctrl_rate
, Brass_cget_rate
, "float", "rate" ); //! rate of change
327 QUERY
->ugen_ctrl( QUERY
, Brass_ctrl_lip
, Brass_cget_lip
, "float", "lip" ); //! lip stiffness
330 QUERY
->ugen_add( QUERY
, "Clarinet", NULL
);
331 QUERY
->ugen_func( QUERY
, Clarinet_ctor
, Clarinet_dtor
, Clarinet_tick
, Clarinet_pmsg
);
332 QUERY
->ugen_ctrl( QUERY
, Clarinet_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! note on
333 QUERY
->ugen_ctrl( QUERY
, Clarinet_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! note on
334 QUERY
->ugen_ctrl( QUERY
, Clarinet_ctrl_clear
, NULL
, "float", "clear" ); //! note on
335 QUERY
->ugen_ctrl( QUERY
, Clarinet_ctrl_startBlowing
, NULL
, "float", "startBlowing" ); //! note on
336 QUERY
->ugen_ctrl( QUERY
, Clarinet_ctrl_stopBlowing
, NULL
, "float", "stopBlowing" ); //! note on
337 QUERY
->ugen_ctrl( QUERY
, Clarinet_ctrl_freq
, Clarinet_cget_freq
, "float", "freq" ); //! frequency
338 QUERY
->ugen_ctrl( QUERY
, Clarinet_ctrl_rate
, Clarinet_cget_rate
, "float", "rate" ); //! rate of change
341 QUERY
->ugen_add( QUERY
, "Flute", NULL
);
342 QUERY
->ugen_func( QUERY
, Flute_ctor
, Flute_dtor
, Flute_tick
, Flute_pmsg
);
343 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! note on
344 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! note on
345 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_clear
, NULL
, "float", "clear" ); //! note on
346 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_startBlowing
, NULL
, "float", "startBlowing" ); //! note on
347 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_stopBlowing
, NULL
, "float", "stopBlowing" ); //! note on
348 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_freq
, Flute_cget_freq
, "float", "freq" ); //! frequency
349 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_rate
, Flute_cget_rate
, "float", "rate" ); //! frequency
350 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_jetReflection
, Flute_cget_jetReflection
, "float", "jetReflection" ); //! rate of change
351 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_jetDelay
, Flute_cget_jetDelay
, "float", "jetDelay" ); //! rate of change
352 QUERY
->ugen_ctrl( QUERY
, Flute_ctrl_endReflection
, Flute_cget_endReflection
, "float", "endReflection" ); //! rate of change
355 //! see \example mand-o-matic.ck
356 QUERY
->ugen_add( QUERY
, "Mandolin", NULL
);
357 QUERY
->ugen_func( QUERY
, Mandolin_ctor
, Mandolin_dtor
, Mandolin_tick
, Mandolin_pmsg
);
358 QUERY
->ugen_ctrl( QUERY
, Mandolin_ctrl_pluck
, NULL
, "float", "pluck" ); //! pluck string with given amplitude
359 QUERY
->ugen_ctrl( QUERY
, Mandolin_ctrl_freq
, Mandolin_cget_freq
, "float", "freq" ); //! string frequency
360 QUERY
->ugen_ctrl( QUERY
, Mandolin_ctrl_pluckPos
, Mandolin_cget_pluckPos
, "float", "pluckPos" ); //! set pluck position ( 0-1) along string
361 QUERY
->ugen_ctrl( QUERY
, Mandolin_ctrl_bodySize
, Mandolin_cget_bodySize
, "float", "bodySize" ); //! modify instrument size
362 QUERY
->ugen_ctrl( QUERY
, Mandolin_ctrl_stringDamping
, Mandolin_cget_stringDamping
, "float", "stringDamping" ); //! control string damping
363 QUERY
->ugen_ctrl( QUERY
, Mandolin_ctrl_stringDetune
, Mandolin_cget_stringDetune
, "float", "stringDetune" ); //! control detuning of string pair
364 QUERY
->ugen_ctrl( QUERY
, Mandolin_ctrl_afterTouch
, NULL
, "float", "afterTouch" ); //!aftertouch
367 //! see \example modalbot.ck
368 QUERY
->ugen_add( QUERY
, "ModalBar", NULL
);
369 QUERY
->ugen_func( QUERY
, ModalBar_ctor
, ModalBar_dtor
, ModalBar_tick
, ModalBar_pmsg
);
370 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_strike
, NULL
, "float", "strike" ); //! strike bar
371 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_damp
, NULL
, "float", "damp" ); //! damp bar
372 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! start note
373 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! stop note
374 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_clear
, NULL
, "float", "clear" ); //! reset
376 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_preset
, ModalBar_cget_preset
, "int", "preset" ); //! choose preset
377 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_freq
, ModalBar_cget_freq
, "float", "freq" ); //! set frequency
378 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_strikePosition
, ModalBar_cget_strikePosition
, "float", "strikePosition" ); //! set frequency
379 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_stickHardness
, ModalBar_cget_stickHardness
, "float", "stickHardness" ); //! set frequency
380 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_masterGain
, ModalBar_cget_masterGain
, "float", "masterGain" ); //! set frequency
381 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_directGain
, ModalBar_cget_directGain
, "float", "directGain" ); //! set frequency
383 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_mode
, ModalBar_cget_mode
, "int", "mode" ); //! choose mode
384 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_modeRatio
, ModalBar_cget_modeRatio
, "float", "modeRatio" ); //! mode edit
385 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_modeRadius
, ModalBar_cget_modeRadius
, "float", "modeRadius" ); //! mode dit
386 QUERY
->ugen_ctrl( QUERY
, ModalBar_ctrl_modeGain
, ModalBar_cget_modeGain
, "float", "modeGain" ); //! mode edit
389 //! see \example moogie.ck
390 QUERY
->ugen_add( QUERY
, "Moog", NULL
);
391 QUERY
->ugen_func( QUERY
, Moog_ctor
, Moog_dtor
, Moog_tick
, Moog_pmsg
);
392 QUERY
->ugen_ctrl( QUERY
, Moog_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! start note
393 QUERY
->ugen_ctrl( QUERY
, Moog_ctrl_freq
, Moog_cget_freq
, "float", "freq" ); //! set frequency
394 QUERY
->ugen_ctrl( QUERY
, Moog_ctrl_modSpeed
, Moog_cget_modSpeed
, "float", "modSpeed" ); //! modulation speed
395 QUERY
->ugen_ctrl( QUERY
, Moog_ctrl_modDepth
, Moog_cget_modDepth
, "float", "modDepth" ); //! modulation depth
396 QUERY
->ugen_ctrl( QUERY
, Moog_ctrl_filterQ
, Moog_cget_filterQ
, "float", "filterQ" ); //! filter Q value
397 QUERY
->ugen_ctrl( QUERY
, Moog_ctrl_filterSweepRate
, Moog_cget_filterSweepRate
, "float", "filterSweepRate" ); //! filter sweep rate
398 QUERY
->ugen_ctrl( QUERY
, Moog_ctrl_afterTouch
, NULL
, "float", "afterTouch" ); // aftertouch
401 QUERY
->ugen_add( QUERY
, "Saxofony", NULL
);
402 QUERY
->ugen_func( QUERY
, Saxofony_ctor
, Saxofony_dtor
, Saxofony_tick
, Saxofony_pmsg
);
403 QUERY
->ugen_ctrl( QUERY
, Saxofony_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! note on
404 QUERY
->ugen_ctrl( QUERY
, Saxofony_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! note on
405 QUERY
->ugen_ctrl( QUERY
, Saxofony_ctrl_clear
, NULL
, "float", "clear" ); //! clear instrument
406 QUERY
->ugen_ctrl( QUERY
, Saxofony_ctrl_startBlowing
, NULL
, "float", "startBlowing" ); //! note on
407 QUERY
->ugen_ctrl( QUERY
, Saxofony_ctrl_stopBlowing
, NULL
, "float", "stopBlowing" ); //! note on
408 QUERY
->ugen_ctrl( QUERY
, Saxofony_ctrl_freq
, Saxofony_cget_freq
, "float", "freq" ); //! frequency
409 QUERY
->ugen_ctrl( QUERY
, Saxofony_ctrl_rate
, Saxofony_cget_rate
, "float", "rate" ); //! frequency
410 QUERY
->ugen_ctrl( QUERY
, Saxofony_ctrl_blowPosition
, Saxofony_cget_blowPosition
, "float", "blowPosition" ); //! lip stiffness
413 //! see \example shake-o-matic.ck
414 QUERY
->ugen_add( QUERY
, "Shakers", NULL
);
415 QUERY
->ugen_func( QUERY
, Shakers_ctor
, Shakers_dtor
, Shakers_tick
, Shakers_pmsg
);
416 QUERY
->ugen_ctrl( QUERY
, Shakers_ctrl_freq
, Shakers_cget_freq
, "float", "freq" ); //! set frequency
417 QUERY
->ugen_ctrl( QUERY
, Shakers_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! start shake with given amplitude
418 QUERY
->ugen_ctrl( QUERY
, Shakers_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! stop shake
419 QUERY
->ugen_ctrl( QUERY
, Shakers_ctrl_which
, Shakers_cget_which
, "int", "which" ); //! select instrument
422 QUERY
->ugen_add( QUERY
, "Sitar", NULL
);
423 QUERY
->ugen_func( QUERY
, Sitar_ctor
, Sitar_dtor
, Sitar_tick
, Sitar_pmsg
);
424 QUERY
->ugen_ctrl( QUERY
, Sitar_ctrl_pluck
, NULL
, "float", "pluck" ); //!
425 QUERY
->ugen_ctrl( QUERY
, Sitar_ctrl_noteOn
, NULL
, "float", "noteOn" );
426 QUERY
->ugen_ctrl( QUERY
, Sitar_ctrl_noteOff
, NULL
, "float", "noteOff" );
427 QUERY
->ugen_ctrl( QUERY
, Sitar_ctrl_clear
, NULL
, "float", "clear" );
428 QUERY
->ugen_ctrl( QUERY
, Sitar_ctrl_freq
, Sitar_cget_freq
, "float", "freq" );
431 //! see \example stifkarp.ck
432 QUERY
->ugen_add( QUERY
, "StifKarp", NULL
);
433 QUERY
->ugen_func( QUERY
, StifKarp_ctor
, StifKarp_dtor
, StifKarp_tick
, StifKarp_pmsg
);
434 QUERY
->ugen_ctrl( QUERY
, StifKarp_ctrl_pluck
, NULL
, "float", "pluck" ); //!
435 QUERY
->ugen_ctrl( QUERY
, StifKarp_ctrl_noteOn
, NULL
, "float", "noteOn" );
436 QUERY
->ugen_ctrl( QUERY
, StifKarp_ctrl_noteOff
, NULL
, "float", "noteOff" );
437 QUERY
->ugen_ctrl( QUERY
, StifKarp_ctrl_clear
, NULL
, "float", "clear" );
438 QUERY
->ugen_ctrl( QUERY
, StifKarp_ctrl_freq
, StifKarp_cget_freq
, "float", "freq" );
439 QUERY
->ugen_ctrl( QUERY
, StifKarp_ctrl_pickupPosition
, StifKarp_cget_pickupPosition
, "float", "pickupPosition" );
440 QUERY
->ugen_ctrl( QUERY
, StifKarp_ctrl_stretch
, StifKarp_cget_stretch
, "float", "stretch" );
441 QUERY
->ugen_ctrl( QUERY
, StifKarp_ctrl_baseLoopGain
, StifKarp_cget_baseLoopGain
, "float", "baseLoopGain" );
444 //! see \example voic-o-form.ck
445 QUERY
->ugen_add( QUERY
, "VoicForm", NULL
);
446 QUERY
->ugen_func( QUERY
, VoicForm_ctor
, VoicForm_dtor
, VoicForm_tick
, VoicForm_pmsg
);
447 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_freq
, VoicForm_cget_freq
, "float", "freq" ); //! frequency
448 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_phoneme
, VoicForm_cget_phoneme
, "string", "phoneme" ); //! select phoneme ( above )
449 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! start note
450 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! stop note
451 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_speak
, NULL
, "float", "speak" ); //! start singing
452 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_quiet
, NULL
, "float", "quiet" ); //! stop singing
453 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_voiced
, VoicForm_cget_voiced
, "float", "voiced" ); //! set mix for voiced component
454 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_unVoiced
, VoicForm_cget_unVoiced
, "float", "unVoiced" ); //! set mix for unvoiced component
455 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_pitchSweepRate
, VoicForm_cget_pitchSweepRate
, "float", "pitchSweepRate" ); //! pitch sweep
456 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_voiceMix
, VoicForm_cget_voiceMix
, "float", "voiceMix" ); //! voiced/unvoiced mix
457 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_selPhoneme
, VoicForm_cget_selPhoneme
, "int", "setPhoneme" ); //! select phoneme by number
458 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_vibratoFreq
, VoicForm_cget_vibratoFreq
, "float", "vibratoFreq" );//! vibrato
459 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_vibratoGain
, VoicForm_cget_vibratoGain
, "float", "vibratoGain" );//! vibrato depth
460 QUERY
->ugen_ctrl( QUERY
, VoicForm_ctrl_loudness
, VoicForm_cget_loudness
, "float", "loudness" ); //! 'loudness' of voicee
462 //! \section2 stk - fm synths
465 QUERY
->ugen_add( QUERY
, "FM", NULL
);
466 QUERY
->ugen_func( QUERY
, FM_ctor
, FM_dtor
, FM_tick
, FM_pmsg
);
467 QUERY
->ugen_ctrl( QUERY
, FM_ctrl_freq
, FM_cget_freq
, "float", "freq" ); //!set frequency
468 QUERY
->ugen_ctrl( QUERY
, FM_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! trigger note
469 QUERY
->ugen_ctrl( QUERY
, FM_ctrl_noteOff
, NULL
, "float", "noteOff" ); //! end note
470 QUERY
->ugen_ctrl( QUERY
, FM_ctrl_modDepth
, NULL
, "float", "modDepth" ); //!modulation Depth
471 QUERY
->ugen_ctrl( QUERY
, FM_ctrl_modSpeed
, NULL
, "float", "modSpeed" ); //!modulation Speed
472 QUERY
->ugen_ctrl( QUERY
, FM_ctrl_afterTouch
, NULL
, "float", "afterTouch" ); //!aftertouch
473 QUERY
->ugen_ctrl( QUERY
, FM_ctrl_control1
, NULL
, "float", "control1" ); //! FM control 1
474 QUERY
->ugen_ctrl( QUERY
, FM_ctrl_control2
, NULL
, "float", "control2" ); //! FM control 2
476 // add FM's subclasses
479 QUERY
->ugen_add( QUERY
, "BeeThree", NULL
);
480 QUERY
->ugen_extends (QUERY
, "FM");
481 QUERY
->ugen_func( QUERY
, BeeThree_ctor
, BeeThree_dtor
, BeeThree_tick
, BeeThree_pmsg
);
482 QUERY
->ugen_ctrl( QUERY
, BeeThree_ctrl_noteOn
, NULL
, "float", "noteOn" ); //!trigger note
485 QUERY
->ugen_add( QUERY
, "FMVoices", NULL
);
486 QUERY
->ugen_extends (QUERY
, "FM");
487 QUERY
->ugen_func( QUERY
, FMVoices_ctor
, FMVoices_dtor
, FMVoices_tick
, FMVoices_pmsg
);
488 QUERY
->ugen_ctrl( QUERY
, FMVoices_ctrl_noteOn
, NULL
, "float", "noteOn" );
489 QUERY
->ugen_ctrl( QUERY
, FMVoices_ctrl_freq
, FMVoices_cget_freq
, "float", "freq" ); //!voice frequency
490 QUERY
->ugen_ctrl( QUERY
, FMVoices_ctrl_vowel
, NULL
, "float", "vowel" ); //!select vowel
491 QUERY
->ugen_ctrl( QUERY
, FMVoices_ctrl_spectralTilt
, NULL
, "float", "spectralTilt" ); //! spectral tilt
492 QUERY
->ugen_ctrl( QUERY
, FMVoices_ctrl_lfoSpeed
, NULL
, "float", "lfoSpeed" ); //!speed of LFO
493 QUERY
->ugen_ctrl( QUERY
, FMVoices_ctrl_lfoDepth
, NULL
, "float", "lfoDepth" ); //!depth of LFO
494 QUERY
->ugen_ctrl( QUERY
, FMVoices_ctrl_adsrTarget
, NULL
, "float", "adsrTarget" ); //!adsr targets
497 QUERY
->ugen_add( QUERY
, "HevyMetl", NULL
);
498 QUERY
->ugen_extends (QUERY
, "FM");
499 QUERY
->ugen_func( QUERY
, HevyMetl_ctor
, HevyMetl_dtor
, HevyMetl_tick
, HevyMetl_pmsg
);
500 QUERY
->ugen_ctrl( QUERY
, HevyMetl_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! trigger note
503 QUERY
->ugen_add( QUERY
, "PercFlut", NULL
);
504 QUERY
->ugen_extends (QUERY
, "FM");
505 QUERY
->ugen_func( QUERY
, PercFlut_ctor
, PercFlut_dtor
, PercFlut_tick
, PercFlut_pmsg
);
506 QUERY
->ugen_ctrl( QUERY
, PercFlut_ctrl_freq
, PercFlut_cget_freq
, "float", "freq" ); //! set frequency
507 QUERY
->ugen_ctrl( QUERY
, PercFlut_ctrl_noteOn
, NULL
, "float", "noteOn" ); //!trigger note
510 //! see \examples rhodey.ck
511 QUERY
->ugen_add( QUERY
, "Rhodey", NULL
);
512 QUERY
->ugen_extends (QUERY
, "FM");
513 QUERY
->ugen_func( QUERY
, Rhodey_ctor
, Rhodey_dtor
, Rhodey_tick
, Rhodey_pmsg
);
514 QUERY
->ugen_ctrl( QUERY
, Rhodey_ctrl_freq
, Rhodey_cget_freq
, "float", "freq" ); //! set frequency
515 QUERY
->ugen_ctrl( QUERY
, Rhodey_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! trigger note
518 QUERY
->ugen_add( QUERY
, "TubeBell", NULL
);
519 QUERY
->ugen_extends (QUERY
, "FM");
520 QUERY
->ugen_func( QUERY
, TubeBell_ctor
, TubeBell_dtor
, TubeBell_tick
, TubeBell_pmsg
);
521 QUERY
->ugen_ctrl( QUERY
, TubeBell_ctrl_freq
, TubeBell_cget_freq
, "float", "freq" ); //! set frequency
522 QUERY
->ugen_ctrl( QUERY
, TubeBell_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! trigger note
525 //! see \examples wurley.ck
526 QUERY
->ugen_add( QUERY
, "Wurley", NULL
);
527 QUERY
->ugen_extends (QUERY
, "FM");
528 QUERY
->ugen_func( QUERY
, Wurley_ctor
, Wurley_dtor
, Wurley_tick
, Wurley_pmsg
);
529 QUERY
->ugen_ctrl( QUERY
, Wurley_ctrl_freq
, Wurley_cget_freq
, "float", "freq" ); //! set frequency
530 QUERY
->ugen_ctrl( QUERY
, Wurley_ctrl_noteOn
, NULL
, "float", "noteOn" ); //! trigger note
534 //! \section stk - delay
537 //! see \example net_relay.ck
538 QUERY
->ugen_add( QUERY
, "Delay", NULL
);
539 QUERY
->ugen_func( QUERY
, Delay_ctor
, Delay_dtor
, Delay_tick
, Delay_pmsg
);
540 QUERY
->ugen_ctrl( QUERY
, Delay_ctrl_delay
, Delay_cget_delay
, "dur", "delay" ); //! length of delay
541 QUERY
->ugen_ctrl( QUERY
, Delay_ctrl_max
, Delay_cget_max
, "dur", "max" ); //! max delay (buffer size)
543 // delay 'subs' not actually extending .
546 QUERY
->ugen_add( QUERY
, "DelayA", NULL
);
547 QUERY
->ugen_func( QUERY
, DelayA_ctor
, DelayA_dtor
, DelayA_tick
, DelayA_pmsg
);
548 QUERY
->ugen_ctrl( QUERY
, DelayA_ctrl_delay
, DelayA_cget_delay
, "dur", "delay" ); //! length of delay
549 QUERY
->ugen_ctrl( QUERY
, DelayA_ctrl_max
, DelayA_cget_max
, "dur", "max" ); //! max delay ( buffer size )
552 //! see \example i-robot.ck
553 QUERY
->ugen_add( QUERY
, "DelayL", NULL
);
554 QUERY
->ugen_func( QUERY
, DelayL_ctor
, DelayL_dtor
, DelayL_tick
, DelayL_pmsg
);
555 QUERY
->ugen_ctrl( QUERY
, DelayL_ctrl_delay
, DelayL_cget_delay
, "dur", "delay" ); //! length of delay
556 QUERY
->ugen_ctrl( QUERY
, DelayL_ctrl_max
, DelayL_cget_max
, "dur", "max" ); //! max delay ( buffer size )
559 QUERY
->ugen_add( QUERY
, "Echo", NULL
);
560 QUERY
->ugen_func( QUERY
, Echo_ctor
, Echo_dtor
, Echo_tick
, Echo_pmsg
);
561 QUERY
->ugen_ctrl( QUERY
, Echo_ctrl_delay
, Echo_cget_delay
, "dur", "delay" ); //! length of echo
562 QUERY
->ugen_ctrl( QUERY
, Echo_ctrl_max
, Echo_cget_max
, "dur", "max" ); //! max delay
563 QUERY
->ugen_ctrl( QUERY
, Echo_ctrl_mix
, Echo_cget_mix
, "float", "mix" ); //! mix level ( wet/dry )
565 //! \section stk - envelopes
568 //! see \example sixty.ck
569 QUERY
->ugen_add( QUERY
, "Envelope", NULL
);
570 QUERY
->ugen_func( QUERY
, Envelope_ctor
, Envelope_dtor
, Envelope_tick
, Envelope_pmsg
);
571 QUERY
->ugen_ctrl( QUERY
, Envelope_ctrl_keyOn
, NULL
, "int", "keyOn" ); //! ramp to 1.0
572 QUERY
->ugen_ctrl( QUERY
, Envelope_ctrl_keyOff
, NULL
, "int", "keyOff" ); //! ramp to 0.0
573 QUERY
->ugen_ctrl( QUERY
, Envelope_ctrl_target
, Envelope_cget_target
, "float", "target" ); //! ramp to arbitrary value.
574 QUERY
->ugen_ctrl( QUERY
, Envelope_ctrl_time
, Envelope_cget_time
, "float", "time" ); //! time to reach target
575 QUERY
->ugen_ctrl( QUERY
, Envelope_ctrl_rate
, Envelope_cget_rate
, "float", "rate"); //! rate of change
576 QUERY
->ugen_ctrl( QUERY
, Envelope_ctrl_value
, Envelope_cget_value
, "float", "value" ); //! set immediate value
579 //! see \example adsr.ck
580 QUERY
->ugen_add( QUERY
, "ADSR", NULL
);
581 QUERY
->ugen_extends ( QUERY
, "Envelope" );
582 QUERY
->ugen_func( QUERY
, ADSR_ctor
, ADSR_dtor
, ADSR_tick
, ADSR_pmsg
);
583 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_keyOn
, NULL
, "int", "keyOn" ); //! start the attack for non-zero values
584 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_keyOff
, NULL
, "int", "keyOff" ); //! start release for non-zero values
585 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_attackTime
, NULL
, "float", "attackTime" ); //! attack time
586 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_attackRate
, ADSR_cget_attackRate
, "float", "attackRate" ); //! attack rate
587 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_decayTime
, NULL
, "float", "decayTime" ); //! decay time
588 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_decayRate
, ADSR_cget_decayRate
, "float", "decayRate" ); //! decay rate
589 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_sustainLevel
, ADSR_cget_sustainLevel
, "float", "sustainLevel" ); //! sustain level
590 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_releaseTime
, NULL
, "float", "releaseTime" ); //! release time
591 QUERY
->ugen_ctrl( QUERY
, ADSR_ctrl_releaseRate
, ADSR_cget_releaseRate
, "float", "releaseRate" ); //! release rate
592 QUERY
->ugen_ctrl( QUERY
, NULL
, ADSR_cget_state
, "int", "state" ); //! attack=0, decay=1 , sustain=2, release=3, done=4
593 //uhhh we are supposed to have target and value here as well.. d'oh
595 //! \section stk - filters
598 QUERY
->ugen_add( QUERY
, "BiQuad", NULL
);
599 QUERY
->ugen_func( QUERY
, BiQuad_ctor
, BiQuad_dtor
, BiQuad_tick
, BiQuad_pmsg
);
600 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_b2
, BiQuad_cget_b2
, "float", "b2" ); //! b2 coefficient
601 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_b1
, BiQuad_cget_b1
, "float", "b1" ); //! b1 coefficient
602 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_b0
, BiQuad_cget_b0
, "float", "b0" ); //! b0 coefficient
603 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_a2
, BiQuad_cget_a2
, "float", "a2" ); //! a2 coefficient
604 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_a1
, BiQuad_cget_a1
, "float", "a1" ); //! a1 coefficient
605 QUERY
->ugen_ctrl( QUERY
, NULL
, BiQuad_cget_a0
, "float", "a0" ); //! a0 coefficient
606 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_pfreq
, NULL
, "float", "pfreq" ); //! set resonance frequency (poles)
607 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_prad
, NULL
, "float", "prad" ); //! pole radius (less than 1 to be stable)
608 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_zfreq
, NULL
, "float", "zfreq" ); //! notch frequency
609 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_zrad
, NULL
, "float", "zrad" ); //! zero radius
610 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_norm
, NULL
, "float", "norm" ); //! normalization
611 QUERY
->ugen_ctrl( QUERY
, BiQuad_ctrl_eqzs
, NULL
, "float", "eqzs" ); //! equal gain zeroes
614 QUERY
->ugen_add( QUERY
, "Filter", NULL
);
615 QUERY
->ugen_func( QUERY
, Filter_ctor
, Filter_dtor
, Filter_tick
, Filter_pmsg
);
616 QUERY
->ugen_ctrl( QUERY
, Filter_ctrl_coefs
, NULL
, "string", "coefs" );
621 QUERY
->ugen_add( QUERY
, "OnePole", NULL
);
622 QUERY
->ugen_func( QUERY
, OnePole_ctor
, OnePole_dtor
, OnePole_tick
, OnePole_pmsg
);
624 QUERY
->ugen_ctrl( QUERY
, OnePole_ctrl_a1
, OnePole_cget_a1
, "float", "a1" ); //! filter coefficient
625 QUERY
->ugen_ctrl( QUERY
, OnePole_ctrl_b0
, OnePole_cget_b0
, "float", "b0" ); //! filter coefficient
626 QUERY
->ugen_ctrl( QUERY
, OnePole_ctrl_pole
, OnePole_cget_pole
, "float", "pole" ); //! set pole position along real axis of z-plane
629 //! see \example powerup.ck
630 QUERY
->ugen_add( QUERY
, "TwoPole", NULL
);
631 QUERY
->ugen_func( QUERY
, TwoPole_ctor
, TwoPole_dtor
, TwoPole_tick
, TwoPole_pmsg
);
632 QUERY
->ugen_ctrl( QUERY
, TwoPole_ctrl_a1
, TwoPole_cget_a1
, "float", "a1" ); //! filter coefficient
633 QUERY
->ugen_ctrl( QUERY
, TwoPole_ctrl_a2
, TwoPole_cget_a2
, "float", "a2" ); //! filter coefficient
634 QUERY
->ugen_ctrl( QUERY
, TwoPole_ctrl_b0
, TwoPole_cget_b0
, "float", "b0" ); //! filter coefficient
635 QUERY
->ugen_ctrl( QUERY
, TwoPole_ctrl_freq
, TwoPole_cget_freq
, "float", "freq" ); //! filter resonance frequency
636 QUERY
->ugen_ctrl( QUERY
, TwoPole_ctrl_radius
, TwoPole_cget_radius
, "float", "radius" ); //! filter resonance radius
637 QUERY
->ugen_ctrl( QUERY
, TwoPole_ctrl_norm
, TwoPole_cget_norm
, "int", "norm" ); //! toggle filter normalization
640 QUERY
->ugen_add( QUERY
, "OneZero", NULL
);
641 QUERY
->ugen_func( QUERY
, OneZero_ctor
, OneZero_dtor
, OneZero_tick
, OneZero_pmsg
);
642 QUERY
->ugen_ctrl( QUERY
, OneZero_ctrl_zero
, OneZero_cget_zero
, "float", "zero" ); //! set zero position
643 QUERY
->ugen_ctrl( QUERY
, OneZero_ctrl_b0
, OneZero_cget_b0
, "float", "b0" ); //! filter coefficient
644 QUERY
->ugen_ctrl( QUERY
, OneZero_ctrl_b1
, OneZero_cget_b1
, "float", "b1" ); //! filter coefficient
647 QUERY
->ugen_add( QUERY
, "TwoZero", NULL
);
648 QUERY
->ugen_func( QUERY
, TwoZero_ctor
, TwoZero_dtor
, TwoZero_tick
, TwoZero_pmsg
);
649 QUERY
->ugen_ctrl( QUERY
, TwoZero_ctrl_b0
, TwoZero_cget_b0
, "float", "b0" ); //! filter coefficient
650 QUERY
->ugen_ctrl( QUERY
, TwoZero_ctrl_b1
, TwoZero_cget_b1
, "float", "b1" ); //! filter coefficient
651 QUERY
->ugen_ctrl( QUERY
, TwoZero_ctrl_b2
, TwoZero_cget_b2
, "float", "b2" ); //! filter coefficient
652 QUERY
->ugen_ctrl( QUERY
, TwoZero_ctrl_freq
, TwoZero_cget_freq
, "float", "freq" ); //! filter notch frequency
653 QUERY
->ugen_ctrl( QUERY
, TwoZero_ctrl_radius
, TwoZero_cget_radius
, "float", "radius" ); //! filter notch radius
656 QUERY
->ugen_add( QUERY
, "PoleZero", NULL
);
657 QUERY
->ugen_func( QUERY
, PoleZero_ctor
, PoleZero_dtor
, PoleZero_tick
, PoleZero_pmsg
);
658 QUERY
->ugen_ctrl( QUERY
, PoleZero_ctrl_a1
, PoleZero_cget_a1
, "float", "a1" ); //! filter coefficient
659 QUERY
->ugen_ctrl( QUERY
, PoleZero_ctrl_b0
, PoleZero_cget_b0
, "float", "b0" ); //! filter coefficient
660 QUERY
->ugen_ctrl( QUERY
, PoleZero_ctrl_b1
, PoleZero_cget_b1
, "float", "b1" ); //! filter coefficient
661 QUERY
->ugen_ctrl( QUERY
, PoleZero_ctrl_blockZero
, PoleZero_cget_blockZero
, "float", "blockZero" ); //! DC blocking filter with given pole position
662 QUERY
->ugen_ctrl( QUERY
, PoleZero_ctrl_allpass
, PoleZero_cget_allpass
, "float", "allpass" ); //!allpass filter with given coefficient
666 //! \section stk-reverbs
669 QUERY
->ugen_add( QUERY
, "JCRev", NULL
);
670 QUERY
->ugen_func( QUERY
, JCRev_ctor
, JCRev_dtor
, JCRev_tick
, JCRev_pmsg
);
671 QUERY
->ugen_ctrl( QUERY
, JCRev_ctrl_mix
, JCRev_cget_mix
, "float", "mix" ); //! mix level
674 QUERY
->ugen_add( QUERY
, "NRev", NULL
);
675 QUERY
->ugen_func( QUERY
, NRev_ctor
, NRev_dtor
, NRev_tick
, NRev_pmsg
);
676 QUERY
->ugen_ctrl( QUERY
, NRev_ctrl_mix
, NRev_cget_mix
, "float", "mix" ); // set effect mix
679 QUERY
->ugen_add( QUERY
, "PRCRev", NULL
);
680 QUERY
->ugen_func( QUERY
, PRCRev_ctor
, PRCRev_dtor
, PRCRev_tick
, PRCRev_pmsg
);
681 QUERY
->ugen_ctrl( QUERY
, PRCRev_ctrl_mix
, PRCRev_cget_mix
, "float", "mix" ); //! mix level
683 //! \section components
686 QUERY
->ugen_add( QUERY
, "Chorus", NULL
);
687 QUERY
->ugen_func( QUERY
, Chorus_ctor
, Chorus_dtor
, Chorus_tick
, Chorus_pmsg
);
688 QUERY
->ugen_ctrl( QUERY
, Chorus_ctrl_modFreq
, Chorus_cget_modFreq
, "float", "modFreq" ); //! modulation frequency
689 QUERY
->ugen_ctrl( QUERY
, Chorus_ctrl_modDepth
, Chorus_cget_modDepth
, "float", "modDepth" ); //! modulation depth
690 QUERY
->ugen_ctrl( QUERY
, Chorus_ctrl_mix
, Chorus_cget_mix
, "float", "mix" ); //! effect mix
693 QUERY
->ugen_add( QUERY
, "Modulate", NULL
);
694 QUERY
->ugen_func( QUERY
, Modulate_ctor
, Modulate_dtor
, Modulate_tick
, Modulate_pmsg
);
695 QUERY
->ugen_ctrl( QUERY
, Modulate_ctrl_vibratoRate
, Modulate_cget_vibratoRate
, "float", "vibratoRate" ); //! set rate of vibrato
696 QUERY
->ugen_ctrl( QUERY
, Modulate_ctrl_vibratoGain
, Modulate_cget_vibratoGain
, "float", "vibratoGain" ); //! gain for vibrato
697 QUERY
->ugen_ctrl( QUERY
, Modulate_ctrl_randomGain
, Modulate_cget_randomGain
, "float", "randomGain" ); //! gain for random contribution
700 QUERY
->ugen_add( QUERY
, "PitShift", NULL
);
701 QUERY
->ugen_func( QUERY
, PitShift_ctor
, PitShift_dtor
, PitShift_tick
, PitShift_pmsg
);
702 QUERY
->ugen_ctrl( QUERY
, PitShift_ctrl_shift
, PitShift_cget_shift
, "float", "shift" ); //! degree of pitch shifting
703 QUERY
->ugen_ctrl( QUERY
, PitShift_ctrl_effectMix
, PitShift_cget_effectMix
, "float", "effectMix" ); //! mix level
706 QUERY
->ugen_add( QUERY
, "SubNoise", NULL
);
707 QUERY
->ugen_func( QUERY
, SubNoise_ctor
, SubNoise_dtor
, SubNoise_tick
, SubNoise_pmsg
);
708 QUERY
->ugen_ctrl( QUERY
, SubNoise_ctrl_rate
, SubNoise_cget_rate
, "int", "rate" ); //! subsampling rate
710 //! \section stk - file i/o
713 QUERY
->ugen_add( QUERY
, "WvIn", NULL
);
714 QUERY
->ugen_func( QUERY
, WvIn_ctor
, WvIn_dtor
, WvIn_tick
, WvIn_pmsg
);
715 QUERY
->ugen_ctrl( QUERY
, WvIn_ctrl_rate
, WvIn_cget_rate
, "float", "rate" ); //! playback rate
716 QUERY
->ugen_ctrl( QUERY
, WvIn_ctrl_path
, WvIn_cget_path
, "string", "path" ); //! specifies file to be played
719 //! see \example dope.ck
720 QUERY
->ugen_add( QUERY
, "WaveLoop", NULL
);
721 QUERY
->ugen_extends ( QUERY
, "WvIn" );
722 QUERY
->ugen_func( QUERY
, WaveLoop_ctor
, WaveLoop_dtor
, WaveLoop_tick
, WaveLoop_pmsg
);
723 QUERY
->ugen_ctrl( QUERY
, WaveLoop_ctrl_freq
, WaveLoop_cget_freq
, "float", "freq" ); //! set frequency of playback ( loops / second )
724 QUERY
->ugen_ctrl( QUERY
, WaveLoop_ctrl_phase
, WaveLoop_cget_phase
, "float", "addPhase" ); //! offset by phase
725 QUERY
->ugen_ctrl( QUERY
, WaveLoop_ctrl_phaseOffset
, WaveLoop_cget_phaseOffset
, "float", "addPhaseOffset" ); //! set phase offset
728 QUERY
->ugen_add( QUERY
, "WvOut", NULL
);
729 QUERY
->ugen_func( QUERY
, WvOut_ctor
, WvOut_dtor
, WvOut_tick
, WvOut_pmsg
);
730 QUERY
->ugen_ctrl( QUERY
, WvOut_ctrl_matFilename
, NULL
, "string", "matFilename"); //!open matlab file for writing
731 QUERY
->ugen_ctrl( QUERY
, WvOut_ctrl_sndFilename
, NULL
, "string", "sndFilename"); //!open snd file for writing
732 QUERY
->ugen_ctrl( QUERY
, WvOut_ctrl_wavFilename
, NULL
, "string", "wavFilename"); //!open WAVE file for writing
733 QUERY
->ugen_ctrl( QUERY
, WvOut_ctrl_rawFilename
, NULL
, "string", "rawFilename"); //!open raw file for writing
734 QUERY
->ugen_ctrl( QUERY
, WvOut_ctrl_aifFilename
, NULL
, "string", "aifFilename"); //!open AIFF file for writing
735 QUERY
->ugen_ctrl( QUERY
, NULL
, WvOut_cget_filename
, "string", "filename" ); //!get filename
736 QUERY
->ugen_ctrl( QUERY
, WvOut_ctrl_record
, WvOut_cget_record
, "int", "record" ); // !start/stop output
737 QUERY
->ugen_ctrl( QUERY
, WvOut_ctrl_closeFile
, NULL
, "string", "closeFile"); //! close file properly
738 QUERY
->ugen_ctrl( QUERY
, WvOut_ctrl_autoPrefix
, WvOut_cget_autoPrefix
, "string", "autoPrefix"); //! set/get auto prefix string
746 /***************************************************/
748 \brief STK envelope base class.
750 This class implements a simple envelope
751 generator which is capable of ramping to
752 a target value by a specified \e rate.
753 It also responds to simple \e keyOn and
754 \e keyOff messages, ramping to 1.0 on
755 keyOn and to 0.0 on keyOff.
757 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
759 /***************************************************/
761 #if !defined(__ENVELOPE_H)
765 class Envelope
: public Stk
769 //! Default constructor.
772 //! Class destructor.
773 virtual ~Envelope(void);
776 virtual void keyOn(void);
779 virtual void keyOff(void);
782 void setRate(MY_FLOAT aRate
);
784 //! Set the \e rate based on a time duration.
785 void setTime(MY_FLOAT aTime
);
787 //! Set the target value.
788 virtual void setTarget(MY_FLOAT aTarget
);
790 //! Set current and target values to \e aValue.
791 virtual void setValue(MY_FLOAT aValue
);
793 //! Return the current envelope \e state (0 = at target, 1 otherwise).
794 virtual int getState(void) const;
796 //! Return one envelope output value.
797 virtual MY_FLOAT
tick(void);
799 //! Return \e vectorSize envelope outputs in \e vector.
800 virtual MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
802 //! Return the last computed output value.
803 MY_FLOAT
lastOut(void) const;
817 /***************************************************/
819 \brief STK ADSR envelope class.
821 This Envelope subclass implements a
822 traditional ADSR (Attack, Decay,
823 Sustain, Release) envelope. It
824 responds to simple keyOn and keyOff
825 messages, keeping track of its state.
826 The \e state = ADSR::DONE after the
827 envelope value reaches 0.0 in the
830 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
832 /***************************************************/
834 #if !defined(__ADSR_H)
838 class ADSR
: public Envelope
843 enum { ATTACK
, DECAY
, SUSTAIN
, RELEASE
, DONE
};
845 //! Default constructor.
848 //! Class destructor.
851 //! Set target = 1, state = \e ADSR::ATTACK.
854 //! Set target = 0, state = \e ADSR::RELEASE.
857 //! Set the attack rate.
858 void setAttackRate(MY_FLOAT aRate
);
860 //! Set the decay rate.
861 void setDecayRate(MY_FLOAT aRate
);
863 //! Set the sustain level.
864 void setSustainLevel(MY_FLOAT aLevel
);
866 //! Set the release rate.
867 void setReleaseRate(MY_FLOAT aRate
);
869 //! Set the attack rate based on a time duration.
870 void setAttackTime(MY_FLOAT aTime
);
872 //! Set the decay rate based on a time duration.
873 void setDecayTime(MY_FLOAT aTime
);
875 //! Set the release rate based on a time duration.
876 void setReleaseTime(MY_FLOAT aTime
);
878 //! Set sustain level and attack, decay, and release state rates based on time durations.
879 void setAllTimes(MY_FLOAT aTime
, MY_FLOAT dTime
, MY_FLOAT sLevel
, MY_FLOAT rTime
);
881 //! Set the target value.
882 void setTarget(MY_FLOAT aTarget
);
884 //! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, DONE).
885 int getState(void) const;
887 //! Set to state = ADSR::SUSTAIN with current and target values of \e aValue.
888 void setValue(MY_FLOAT aValue
);
890 //! Return one envelope output value.
893 //! Return \e vectorSize envelope outputs in \e vector.
894 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
899 MY_FLOAT sustainLevel
;
900 MY_FLOAT releaseRate
;
908 /***************************************************/
910 \brief STK instrument abstract base class.
912 This class provides a common interface for
915 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
917 /***************************************************/
919 #if !defined(__INSTRMNT_H)
924 class Instrmnt
: public Stk
927 //! Default constructor.
930 //! Class destructor.
933 //! Start a note with the given frequency and amplitude.
934 virtual void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
) = 0;
936 //! Stop a note with the given amplitude (speed of decay).
937 virtual void noteOff(MY_FLOAT amplitude
) = 0;
939 //! Set instrument parameters for a particular frequency.
940 virtual void setFrequency(MY_FLOAT frequency
);
942 //! Return the last output value.
943 MY_FLOAT
lastOut() const;
945 //! Return the last left output value.
946 MY_FLOAT
lastOutLeft() const;
948 //! Return the last right output value.
949 MY_FLOAT
lastOutRight() const;
951 //! Compute one output sample.
952 virtual MY_FLOAT
tick() = 0;
954 //! Computer \e vectorSize outputs and return them in \e vector.
955 virtual MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
957 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
958 virtual void controlChange(int number
, MY_FLOAT value
);
960 public: // SWAP formerly protected
970 /***************************************************/
972 \brief STK filter class.
974 This class implements a generic structure which
975 can be used to create a wide range of filters.
976 It can function independently or be subclassed
977 to provide more specific controls based on a
978 particular filter type.
980 In particular, this class implements the standard
983 a[0]*y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb] -
984 a[1]*y[n-1] - ... - a[na]*y[n-na]
986 If a[0] is not equal to 1, the filter coeffcients
987 are normalized by a[0].
989 The \e gain parameter is applied at the filter
990 input and does not affect the coefficient values.
991 The default gain value is 1.0. This structure
992 results in one extra multiply per computed sample,
993 but allows easy control of the overall filter gain.
995 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
997 /***************************************************/
999 #if !defined(__FILTER_H)
1003 class Filter
: public Stk
1006 //! Default constructor creates a zero-order pass-through "filter".
1009 //! Overloaded constructor which takes filter coefficients.
1011 An StkError can be thrown if either \e nb or \e na is less than
1012 one, or if the a[0] coefficient is equal to zero.
1014 Filter(int nb
, MY_FLOAT
*bCoefficients
, int na
, MY_FLOAT
*aCoefficients
);
1016 //! Class destructor.
1017 virtual ~Filter(void);
1019 //! Clears all internal states of the filter.
1022 //! Set filter coefficients.
1024 An StkError can be thrown if either \e nb or \e na is less than
1025 one, or if the a[0] coefficient is equal to zero. If a[0] is not
1026 equal to 1, the filter coeffcients are normalized by a[0].
1028 void setCoefficients(int nb
, MY_FLOAT
*bCoefficients
, int na
, MY_FLOAT
*aCoefficients
);
1030 //! Set numerator coefficients.
1032 An StkError can be thrown if \e nb is less than one. Any
1033 previously set denominator coefficients are left unaffected.
1034 Note that the default constructor sets the single denominator
1035 coefficient a[0] to 1.0.
1037 void setNumerator(int nb
, MY_FLOAT
*bCoefficients
);
1039 //! Set denominator coefficients.
1041 An StkError can be thrown if \e na is less than one or if the
1042 a[0] coefficient is equal to zero. Previously set numerator
1043 coefficients are unaffected unless a[0] is not equal to 1, in
1044 which case all coeffcients are normalized by a[0]. Note that the
1045 default constructor sets the single numerator coefficient b[0]
1048 void setDenominator(int na
, MY_FLOAT
*aCoefficients
);
1050 //! Set the filter gain.
1052 The gain is applied at the filter input and does not affect the
1053 coefficient values. The default gain value is 1.0.
1055 virtual void setGain(MY_FLOAT theGain
);
1057 //! Return the current filter gain.
1058 virtual MY_FLOAT
getGain(void) const;
1060 //! Return the last computed output value.
1061 virtual MY_FLOAT
lastOut(void) const;
1063 //! Input one sample to the filter and return one output.
1064 virtual MY_FLOAT
tick(MY_FLOAT sample
);
1066 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
1067 virtual MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
1085 /***************************************************/
1087 \brief STK non-interpolating delay line class.
1089 This protected Filter subclass implements
1090 a non-interpolating digital delay-line.
1091 A fixed maximum length of 4095 and a delay
1092 of zero is set using the default constructor.
1093 Alternatively, the delay and maximum length
1094 can be set during instantiation with an
1095 overloaded constructor.
1097 A non-interpolating delay line is typically
1098 used in fixed delay-length applications, such
1099 as for reverberation.
1101 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
1103 /***************************************************/
1105 #if !defined(__DELAY_H)
1109 class Delay
: public Filter
1113 //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay.
1116 //! Overloaded constructor which specifies the current and maximum delay-line lengths.
1117 Delay(long theDelay
, long maxDelay
);
1119 //! Class destructor.
1122 //! Clears the internal state of the delay line.
1125 //! Set the delay-line length.
1127 The valid range for \e theDelay is from 0 to the maximum delay-line length.
1129 void setDelay(long theDelay
);
1130 void set( long delay
, long max
);
1132 //! Return the current delay-line length.
1133 MY_FLOAT
getDelay(void) const;
1135 //! Calculate and return the signal energy in the delay-line.
1136 MY_FLOAT
energy(void) const;
1138 //! Return the value at \e tapDelay samples from the delay-line input.
1140 The tap point is determined modulo the delay-line length and is
1141 relative to the last input value (i.e., a tapDelay of zero returns
1142 the last input value).
1144 MY_FLOAT
contentsAt(unsigned long tapDelay
) const;
1146 //! Return the last computed output value.
1147 MY_FLOAT
lastOut(void) const;
1149 //! Return the value which will be output by the next call to tick().
1151 This method is valid only for delay settings greater than zero!
1153 virtual MY_FLOAT
nextOut(void) const;
1155 //! Input one sample to the delay-line and return one output.
1156 virtual MY_FLOAT
tick(MY_FLOAT sample
);
1158 //! Input \e vectorSize samples to the delay-line and return an equal number of outputs in \e vector.
1159 virtual MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
1173 /***************************************************/
1175 \brief STK linear interpolating delay line class.
1177 This Delay subclass implements a fractional-
1178 length digital delay-line using first-order
1179 linear interpolation. A fixed maximum length
1180 of 4095 and a delay of zero is set using the
1181 default constructor. Alternatively, the
1182 delay and maximum length can be set during
1183 instantiation with an overloaded constructor.
1185 Linear interpolation is an efficient technique
1186 for achieving fractional delay lengths, though
1187 it does introduce high-frequency signal
1188 attenuation to varying degrees depending on the
1189 fractional delay setting. The use of higher
1190 order Lagrange interpolators can typically
1191 improve (minimize) this attenuation characteristic.
1193 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
1195 /***************************************************/
1197 #if !defined(__DELAYL_H)
1201 class DelayL
: public Delay
1205 //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay.
1208 //! Overloaded constructor which specifies the current and maximum delay-line lengths.
1210 DelayL(MY_FLOAT theDelay
, long maxDelay
);
1212 //! Class destructor.
1215 //! Set the delay-line length.
1217 The valid range for \e theDelay is from 0 to the maximum delay-line length.
1219 void setDelay(MY_FLOAT theDelay
);
1220 void set( MY_FLOAT delay
, long max
);
1222 //! Return the value which will be output by the next call to tick().
1224 This method is valid only for delay settings greater than zero!
1226 MY_FLOAT
nextOut(void);
1228 //! Input one sample to the delay-line and return one output.
1229 MY_FLOAT
tick(MY_FLOAT sample
);
1231 public: // SWAP formerly protected
1234 MY_FLOAT nextOutput
;
1243 /***************************************************/
1245 \brief STK bowed string table class.
1247 This class implements a simple bowed string
1248 non-linear function, as described by Smith (1986).
1250 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
1252 /***************************************************/
1254 #if !defined(__BOWTABL_H)
1258 class BowTabl
: public Stk
1261 //! Default constructor.
1264 //! Class destructor.
1267 //! Set the table offset value.
1269 The table offset is a bias which controls the
1270 symmetry of the friction. If you want the
1271 friction to vary with direction, use a non-zero
1272 value for the offset. The default value is zero.
1274 void setOffset(MY_FLOAT aValue
);
1276 //! Set the table slope value.
1278 The table slope controls the width of the friction
1279 pulse, which is related to bow force.
1281 void setSlope(MY_FLOAT aValue
);
1283 //! Return the last output value.
1284 MY_FLOAT
lastOut(void) const;
1286 //! Return the function value for \e input.
1288 The function input represents differential
1289 string-to-bow velocity.
1291 MY_FLOAT
tick(const MY_FLOAT input
);
1293 //! Take \e vectorSize inputs and return the corresponding function values in \e vector.
1294 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
1296 public: // SWAP formerly protected
1299 MY_FLOAT lastOutput
;
1308 /***************************************************/
1310 \brief STK biquad (two-pole, two-zero) filter class.
1312 This protected Filter subclass implements a
1313 two-pole, two-zero digital filter. A method
1314 is provided for creating a resonance in the
1315 frequency response while maintaining a constant
1318 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
1320 /***************************************************/
1322 #if !defined(__BIQUAD_H)
1326 class BiQuad
: public Filter
1330 //! Default constructor creates a second-order pass-through filter.
1333 //! Class destructor.
1336 //! Clears all internal states of the filter.
1339 //! Set the b[0] coefficient value.
1340 void setB0(MY_FLOAT b0
);
1342 //! Set the b[1] coefficient value.
1343 void setB1(MY_FLOAT b1
);
1345 //! Set the b[2] coefficient value.
1346 void setB2(MY_FLOAT b2
);
1348 //! Set the a[1] coefficient value.
1349 void setA1(MY_FLOAT a1
);
1351 //! Set the a[2] coefficient value.
1352 void setA2(MY_FLOAT a2
);
1354 //! Sets the filter coefficients for a resonance at \e frequency (in Hz).
1356 This method determines the filter coefficients corresponding to
1357 two complex-conjugate poles with the given \e frequency (in Hz)
1358 and \e radius from the z-plane origin. If \e normalize is true,
1359 the filter zeros are placed at z = 1, z = -1, and the coefficients
1360 are then normalized to produce a constant unity peak gain
1361 (independent of the filter \e gain parameter). The resulting
1362 filter frequency response has a resonance at the given \e
1363 frequency. The closer the poles are to the unit-circle (\e radius
1364 close to one), the narrower the resulting resonance width.
1366 void setResonance(MY_FLOAT frequency
, MY_FLOAT radius
, bool normalize
= FALSE
);
1368 //! Set the filter coefficients for a notch at \e frequency (in Hz).
1370 This method determines the filter coefficients corresponding to
1371 two complex-conjugate zeros with the given \e frequency (in Hz)
1372 and \e radius from the z-plane origin. No filter normalization
1375 void setNotch(MY_FLOAT frequency
, MY_FLOAT radius
);
1377 //! Sets the filter zeroes for equal resonance gain.
1379 When using the filter as a resonator, zeroes places at z = 1, z
1380 = -1 will result in a constant gain at resonance of 1 / (1 - R),
1381 where R is the pole radius setting.
1384 void setEqualGainZeroes();
1386 //! Set the filter gain.
1388 The gain is applied at the filter input and does not affect the
1389 coefficient values. The default gain value is 1.0.
1391 void setGain(MY_FLOAT theGain
);
1393 //! Return the current filter gain.
1394 MY_FLOAT
getGain(void) const;
1396 //! Return the last computed output value.
1397 MY_FLOAT
lastOut(void) const;
1399 //! Input one sample to the filter and return one output.
1400 MY_FLOAT
tick(MY_FLOAT sample
);
1402 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
1403 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
1411 /***************************************************/
1413 \brief Banded waveguide modeling class.
1415 This class uses banded waveguide techniques to
1416 model a variety of sounds, including bowed
1417 bars, glasses, and bowls. For more
1418 information, see Essl, G. and Cook, P. "Banded
1419 Waveguides: Towards Physical Modelling of Bar
1420 Percussion Instruments", Proceedings of the
1421 1999 International Computer Music Conference.
1423 Control Change Numbers:
1426 - Strike Position = 8 (not implemented)
1427 - Vibrato Frequency = 11
1429 - Bow Velocity = 128
1431 - Instrument Presets = 16
1434 - Glass Harmonica = 2
1437 by Georg Essl, 1999 - 2002.
1438 Modified for Stk 4.0 by Gary Scavone.
1440 /***************************************************/
1442 #if !defined(__BANDEDWG_H)
1443 #define __BANDEDWG_H
1445 #define MAX_BANDED_MODES 20
1448 class BandedWG
: public Instrmnt
1451 //! Class constructor.
1454 //! Class destructor.
1457 //! Reset and clear all internal state.
1460 //! Set strike position (0.0 - 1.0).
1461 void setStrikePosition(MY_FLOAT position
);
1463 //! Select a preset.
1464 void setPreset(int preset
);
1466 //! Set instrument parameters for a particular frequency.
1467 void setFrequency(MY_FLOAT frequency
);
1469 //! Apply bow velocity/pressure to instrument with given amplitude and rate of increase.
1470 void startBowing(MY_FLOAT amplitude
, MY_FLOAT rate
);
1472 //! Decrease bow velocity/breath pressure with given rate of decrease.
1473 void stopBowing(MY_FLOAT rate
);
1475 //! Pluck the instrument with given amplitude.
1476 void pluck(MY_FLOAT amp
);
1478 //! Start a note with the given frequency and amplitude.
1479 void noteOn(MY_FLOAT amplitude
) { noteOn ( freakency
, amplitude
); }
1480 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
1482 //! Stop a note with the given amplitude (speed of decay).
1483 void noteOff(MY_FLOAT amplitude
);
1485 //! Compute one output sample.
1488 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
1489 void controlChange(int number
, MY_FLOAT value
);
1491 public: // SWAP formerly protected
1495 double m_bowpressure
;
1505 MY_FLOAT maxVelocity
;
1506 MY_FLOAT modes
[MAX_BANDED_MODES
];
1509 MY_FLOAT gains
[MAX_BANDED_MODES
];
1510 MY_FLOAT basegains
[MAX_BANDED_MODES
];
1511 MY_FLOAT excitation
[MAX_BANDED_MODES
];
1512 MY_FLOAT integrationConstant
;
1513 MY_FLOAT velocityInput
;
1514 MY_FLOAT bowVelocity
;
1516 MY_FLOAT bowPosition
;
1527 /***************************************************/
1529 \brief STK audio data input base class.
1531 This class provides input support for various
1532 audio file formats. It also serves as a base
1533 class for "realtime" streaming subclasses.
1535 WvIn loads the contents of an audio file for
1536 subsequent output. Linear interpolation is
1537 used for fractional "read rates".
1539 WvIn supports multi-channel data in interleaved
1540 format. It is important to distinguish the
1541 tick() methods, which return samples produced
1542 by averaging across sample frames, from the
1543 tickFrame() methods, which return pointers to
1544 multi-channel sample frames. For single-channel
1545 data, these methods return equivalent values.
1547 Small files are completely read into local memory
1548 during instantiation. Large files are read
1549 incrementally from disk. The file size threshold
1550 and the increment size values are defined in
1553 WvIn currently supports WAV, AIFF, SND (AU),
1554 MAT-file (Matlab), and STK RAW file formats.
1555 Signed integer (8-, 16-, and 32-bit) and floating-
1556 point (32- and 64-bit) data types are supported.
1557 Uncompressed data types are not supported. If
1558 using MAT-files, data should be saved in an array
1559 with each data channel filling a matrix row.
1561 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
1563 /***************************************************/
1565 #if !defined(__WVIN_H)
1568 // Files larger than CHUNK_THRESHOLD will be copied into memory
1569 // in CHUNK_SIZE increments, rather than completely loaded into
1570 // a buffer at once.
1572 #define CHUNK_THRESHOLD 5000000 // 5 Mb
1573 #define CHUNK_SIZE 1024 // sample frames
1577 class WvIn
: public Stk
1580 //! Default constructor.
1583 //! Overloaded constructor for file input.
1585 An StkError will be thrown if the file is not found, its format is
1586 unknown, or a read error occurs.
1588 WvIn( const char *fileName
, bool raw
= FALSE
, bool doNormalize
= TRUE
, bool generate
=true );
1590 //! Class destructor.
1593 //! Open the specified file and load its data.
1595 An StkError will be thrown if the file is not found, its format is
1596 unknown, or a read error occurs.
1598 virtual void openFile( const char *fileName
, bool raw
= FALSE
, bool doNormalize
= TRUE
, bool generate
= true );
1600 //! If a file is open, close it.
1601 void closeFile(void);
1603 //! Clear outputs and reset time (file pointer) to zero.
1606 //! Normalize data to a maximum of +-1.0.
1608 For large, incrementally loaded files with integer data types,
1609 normalization is computed relative to the data type maximum.
1610 No normalization is performed for incrementally loaded files
1611 with floating-point data types.
1613 void normalize(void);
1615 //! Normalize data to a maximum of \e +-peak.
1617 For large, incrementally loaded files with integer data types,
1618 normalization is computed relative to the data type maximum
1619 (\e peak/maximum). For incrementally loaded files with floating-
1620 point data types, direct scaling by \e peak is performed.
1622 void normalize(MY_FLOAT peak
);
1624 //! Return the file size in sample frames.
1625 unsigned long getSize(void) const;
1627 //! Return the number of audio channels in the file.
1628 unsigned int getChannels(void) const;
1630 //! Return the input file sample rate in Hz (not the data read rate).
1632 WAV, SND, and AIF formatted files specify a sample rate in
1633 their headers. STK RAW files have a sample rate of 22050 Hz
1634 by definition. MAT-files are assumed to have a rate of 44100 Hz.
1636 MY_FLOAT
getFileRate(void) const;
1638 //! Query whether reading is complete.
1639 bool isFinished(void) const;
1641 //! Set the data read rate in samples. The rate can be negative.
1643 If the rate value is negative, the data is read in reverse order.
1645 void setRate(MY_FLOAT aRate
);
1647 //! Increment the read pointer by \e aTime samples.
1648 virtual void addTime(MY_FLOAT aTime
);
1650 //! Turn linear interpolation on/off.
1652 Interpolation is automatically off when the read rate is
1653 an integer value. If interpolation is turned off for a
1654 fractional rate, the time index is truncated to an integer
1657 void setInterpolate(bool doInterpolate
);
1659 //! Return the average across the last output sample frame.
1660 virtual MY_FLOAT
lastOut(void) const;
1662 //! Read out the average across one sample frame of data.
1664 An StkError will be thrown if a file is read incrementally and a read error occurs.
1666 virtual MY_FLOAT
tick(void);
1668 //! Read out vectorSize averaged sample frames of data in \e vector.
1670 An StkError will be thrown if a file is read incrementally and a read error occurs.
1672 virtual MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
1674 //! Return a pointer to the last output sample frame.
1675 virtual const MY_FLOAT
*lastFrame(void) const;
1677 //! Return a pointer to the next sample frame of data.
1679 An StkError will be thrown if a file is read incrementally and a read error occurs.
1681 virtual const MY_FLOAT
*tickFrame(void);
1683 //! Read out sample \e frames of data to \e frameVector.
1685 An StkError will be thrown if a file is read incrementally and a read error occurs.
1687 virtual MY_FLOAT
*tickFrame(MY_FLOAT
*frameVector
, unsigned int frames
);
1689 public: // SWAP formerly protected
1691 // Initialize class variables.
1695 virtual void readData(unsigned long index
);
1697 // Get STK RAW file information.
1698 bool getRawInfo( const char *fileName
);
1700 // Get WAV file header information.
1701 bool getWavInfo( const char *fileName
);
1703 // Get SND (AU) file header information.
1704 bool getSndInfo( const char *fileName
);
1706 // Get AIFF file header information.
1707 bool getAifInfo( const char *fileName
);
1709 // Get MAT-file header information.
1710 bool getMatInfo( const char *fileName
);
1713 char m_filename
[256]; // chuck data
1716 MY_FLOAT
*lastOutput
;
1721 unsigned long fileSize
;
1722 unsigned long bufferSize
;
1723 unsigned long dataOffset
;
1724 unsigned int channels
;
1726 STK_FORMAT dataType
;
1735 #endif // defined(__WVIN_H)
1740 /***************************************************/
1742 \brief STK waveform oscillator class.
1744 This class inherits from WvIn and provides
1745 audio file looping functionality.
1747 WaveLoop supports multi-channel data in
1748 interleaved format. It is important to
1749 distinguish the tick() methods, which return
1750 samples produced by averaging across sample
1751 frames, from the tickFrame() methods, which
1752 return pointers to multi-channel sample frames.
1753 For single-channel data, these methods return
1756 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
1758 /***************************************************/
1760 #if !defined(__WAVELOOP_H)
1761 #define __WAVELOOP_H
1765 class WaveLoop
: public WvIn
1769 //! Class constructor.
1770 WaveLoop( const char *fileName
, bool raw
= FALSE
, bool generate
= true );
1772 virtual void openFile( const char * fileName
, bool raw
= FALSE
, bool n
= TRUE
);
1774 //! Class destructor.
1775 virtual ~WaveLoop();
1777 //! Set the data interpolation rate based on a looping frequency.
1779 This function determines the interpolation rate based on the file
1780 size and the current Stk::sampleRate. The \e aFrequency value
1781 corresponds to file cycles per second. The frequency can be
1782 negative, in which case the loop is read in reverse order.
1784 void setFrequency(MY_FLOAT aFrequency
);
1786 //! Increment the read pointer by \e aTime samples, modulo file size.
1787 void addTime(MY_FLOAT aTime
);
1789 //! Increment current read pointer by \e anAngle, relative to a looping frequency.
1791 This function increments the read pointer based on the file
1792 size and the current Stk::sampleRate. The \e anAngle value
1793 is a multiple of file size.
1795 void addPhase(MY_FLOAT anAngle
);
1797 //! Add a phase offset to the current read pointer.
1799 This function determines a time offset based on the file
1800 size and the current Stk::sampleRate. The \e anAngle value
1801 is a multiple of file size.
1803 void addPhaseOffset(MY_FLOAT anAngle
);
1805 //! Return a pointer to the next sample frame of data.
1806 const MY_FLOAT
*tickFrame(void);
1811 void readData(unsigned long index
);
1812 MY_FLOAT phaseOffset
;
1813 MY_FLOAT m_freq
; // chuck data;
1816 #endif // defined(__WAVELOOP_H)
1821 /***************************************************/
1823 \brief STK two-zero filter class.
1825 This protected Filter subclass implements
1826 a two-zero digital filter. A method is
1827 provided for creating a "notch" in the
1828 frequency response while maintaining a
1829 constant filter gain.
1831 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
1833 /***************************************************/
1835 #if !defined(__TWOZERO_H)
1839 class TwoZero
: public Filter
// formerly protected Filter
1842 //! Default constructor creates a second-order pass-through filter.
1845 //! Class destructor.
1848 //! Clears the internal states of the filter.
1851 //! Set the b[0] coefficient value.
1852 void setB0(MY_FLOAT b0
);
1854 //! Set the b[1] coefficient value.
1855 void setB1(MY_FLOAT b1
);
1857 //! Set the b[2] coefficient value.
1858 void setB2(MY_FLOAT b2
);
1860 //! Sets the filter coefficients for a "notch" at \e frequency (in Hz).
1862 This method determines the filter coefficients corresponding to
1863 two complex-conjugate zeros with the given \e frequency (in Hz)
1864 and \e radius from the z-plane origin. The coefficients are then
1865 normalized to produce a maximum filter gain of one (independent of
1866 the filter \e gain parameter). The resulting filter frequency
1867 response has a "notch" or anti-resonance at the given \e
1868 frequency. The closer the zeros are to the unit-circle (\e radius
1869 close to or equal to one), the narrower the resulting notch width.
1871 void setNotch(MY_FLOAT frequency
, MY_FLOAT radius
);
1873 void ck_setNotchFreq ( MY_FLOAT freq
) { m_notchFreq
= freq
; setNotch (m_notchFreq
, m_notchRad
); }
1874 void ck_setNotchRad ( MY_FLOAT rad
) { m_notchRad
= rad
; setNotch (m_notchFreq
, m_notchRad
); }
1877 //chuck helper functions
1878 MY_FLOAT m_notchFreq
;
1879 MY_FLOAT m_notchRad
;
1881 //! Set the filter gain.
1883 The gain is applied at the filter input and does not affect the
1884 coefficient values. The default gain value is 1.0.
1886 void setGain(MY_FLOAT theGain
);
1888 //! Return the current filter gain.
1889 MY_FLOAT
getGain(void) const;
1891 //! Return the last computed output value.
1892 MY_FLOAT
lastOut(void) const;
1894 //! Input one sample to the filter and return one output.
1895 MY_FLOAT
tick(MY_FLOAT sample
);
1897 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
1898 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
1906 /***************************************************/
1908 \brief STK abstract FM synthesis base class.
1910 This class controls an arbitrary number of
1911 waves and envelopes, determined via a
1912 constructor argument.
1914 Control Change Numbers:
1919 - ADSR 2 & 4 Target = 128
1921 The basic Chowning/Stanford FM patent expired
1922 in 1995, but there exist follow-on patents,
1923 mostly assigned to Yamaha. If you are of the
1924 type who should worry about this (making
1927 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
1929 /***************************************************/
1931 #if !defined(__FM_H)
1935 class FM
: public Instrmnt
1938 //! Class constructor, taking the number of wave/envelope operators to control.
1939 FM( int operators
= 4 );
1941 //! Class destructor.
1944 //! Reset and clear all wave and envelope states.
1947 //! Load the rawwave filenames in waves.
1948 void loadWaves(const char **filenames
);
1950 //! Set instrument parameters for a particular frequency.
1951 virtual void setFrequency(MY_FLOAT frequency
);
1953 //! Set the frequency ratio for the specified wave.
1954 void setRatio(int waveIndex
, MY_FLOAT ratio
);
1956 //! Set the gain for the specified wave.
1957 void setGain(int waveIndex
, MY_FLOAT gain
);
1959 //! Set the modulation speed in Hz.
1960 void setModulationSpeed(MY_FLOAT mSpeed
);
1962 //! Set the modulation depth.
1963 void setModulationDepth(MY_FLOAT mDepth
);
1965 //! Set the value of control1.
1966 void setControl1(MY_FLOAT cVal
);
1968 //! Set the value of control1.
1969 void setControl2(MY_FLOAT cVal
);
1971 //! Start envelopes toward "on" targets.
1974 //! Start envelopes toward "off" targets.
1977 //! Stop a note with the given amplitude (speed of decay).
1978 void noteOff(MY_FLOAT amplitude
);
1980 //! Pure virtual function ... must be defined in subclasses.
1981 virtual MY_FLOAT
tick() = 0;
1983 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
1984 virtual void controlChange(int number
, MY_FLOAT value
);
1986 public: // SWAP formerly protected
1992 MY_FLOAT baseFrequency
;
1998 MY_FLOAT __FM_gains
[100];
1999 MY_FLOAT __FM_susLevels
[16];
2000 MY_FLOAT __FM_attTimes
[32];
2009 /***************************************************/
2011 \brief STK Hammond-oid organ FM synthesis instrument.
2013 This class implements a simple 4 operator
2014 topology, also referred to as algorithm 8 of
2026 Control Change Numbers:
2027 - Operator 4 (feedback) Gain = 2
2028 - Operator 3 Gain = 4
2031 - ADSR 2 & 4 Target = 128
2033 The basic Chowning/Stanford FM patent expired
2034 in 1995, but there exist follow-on patents,
2035 mostly assigned to Yamaha. If you are of the
2036 type who should worry about this (making
2039 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2041 /***************************************************/
2043 #if !defined(__BEETHREE_H)
2044 #define __BEETHREE_H
2047 class BeeThree
: public FM
2050 //! Class constructor.
2053 //! Class destructor.
2056 //! Start a note with the given frequency and amplitude.
2057 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
2058 void noteOn( MY_FLOAT amplitude
) { noteOn( baseFrequency
, amplitude
); }
2059 //! Compute one output sample.
2068 /***************************************************/
2070 \brief STK jet table class.
2072 This class implements a flue jet non-linear
2073 function, computed by a polynomial calculation.
2074 Contrary to the name, this is not a "table".
2076 Consult Fletcher and Rossing, Karjalainen,
2077 Cook, and others for more information.
2079 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2081 /***************************************************/
2083 #if !defined(__JETTABL_H)
2087 class JetTabl
: public Stk
2090 //! Default constructor.
2093 //! Class destructor.
2096 //! Return the last output value.
2097 MY_FLOAT
lastOut() const;
2099 //! Return the function value for \e input.
2100 MY_FLOAT
tick(MY_FLOAT input
);
2102 //! Take \e vectorSize inputs and return the corresponding function values in \e vector.
2103 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
2105 public: // SWAP formerly protected
2106 MY_FLOAT lastOutput
;
2115 /***************************************************/
2117 \brief STK one-pole, one-zero filter class.
2119 This protected Filter subclass implements
2120 a one-pole, one-zero digital filter. A
2121 method is provided for creating an allpass
2122 filter with a given coefficient. Another
2123 method is provided to create a DC blocking filter.
2125 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2127 /***************************************************/
2129 #if !defined(__POLEZERO_H)
2130 #define __POLEZERO_H
2133 class PoleZero
: public Filter
// formerly protected Filter
2137 //! Default constructor creates a first-order pass-through filter.
2140 //! Class destructor.
2143 //! Clears the internal states of the filter.
2146 //! Set the b[0] coefficient value.
2147 void setB0(MY_FLOAT b0
);
2149 //! Set the b[1] coefficient value.
2150 void setB1(MY_FLOAT b1
);
2152 //! Set the a[1] coefficient value.
2153 void setA1(MY_FLOAT a1
);
2155 //! Set the filter for allpass behavior using \e coefficient.
2157 This method uses \e coefficient to create an allpass filter,
2158 which has unity gain at all frequencies. Note that the \e
2159 coefficient magnitude must be less than one to maintain stability.
2161 void setAllpass(MY_FLOAT coefficient
);
2163 //! Create a DC blocking filter with the given pole position in the z-plane.
2165 This method sets the given pole position, together with a zero
2166 at z=1, to create a DC blocking filter. \e thePole should be
2167 close to one to minimize low-frequency attenuation.
2170 void setBlockZero(MY_FLOAT thePole
= 0.99);
2172 //! Set the filter gain.
2174 The gain is applied at the filter input and does not affect the
2175 coefficient values. The default gain value is 1.0.
2177 void setGain(MY_FLOAT theGain
);
2179 //! Return the current filter gain.
2180 MY_FLOAT
getGain(void) const;
2182 //! Return the last computed output value.
2183 MY_FLOAT
lastOut(void) const;
2185 //! Input one sample to the filter and return one output.
2186 MY_FLOAT
tick(MY_FLOAT sample
);
2188 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
2189 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
2197 /***************************************************/
2199 \brief STK noise generator.
2201 Generic random number generation using the
2202 C rand() function. The quality of the rand()
2203 function varies from one OS to another.
2205 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2207 /***************************************************/
2209 #if !defined(__NOISE_H)
2213 class Noise
: public Stk
2217 //! Default constructor which seeds the random number generator with the system time.
2220 //! Constructor which seeds the random number generator with a given seed.
2222 If the seed value is zero, the random number generator is
2223 seeded with the system time.
2225 Noise( unsigned int seed
);
2227 //! Class destructor.
2230 //! Seed the random number generator with a specific seed value.
2232 If no seed is provided or the seed value is zero, the random
2233 number generator is seeded with the current system time.
2235 void setSeed( unsigned int seed
= 0 );
2237 //! Return a random number between -1.0 and 1.0 using rand().
2238 virtual MY_FLOAT
tick();
2240 //! Return \e vectorSize random numbers between -1.0 and 1.0 in \e vector.
2241 virtual MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
2243 //! Return the last computed value.
2244 MY_FLOAT
lastOut() const;
2246 public: // SWAP formerly protected
2248 MY_FLOAT lastOutput
;
2257 /***************************************************/
2259 \brief STK blown bottle instrument class.
2261 This class implements a helmholtz resonator
2262 (biquad filter) with a polynomial jet
2263 excitation (a la Cook).
2265 Control Change Numbers:
2267 - Vibrato Frequency = 11
2271 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2273 /***************************************************/
2275 #if !defined(__BOTTLE_H)
2279 class BlowBotl
: public Instrmnt
2282 //! Class constructor.
2285 //! Class destructor.
2288 //! Reset and clear all internal state.
2291 //! Set instrument parameters for a particular frequency.
2292 void setFrequency(MY_FLOAT frequency
);
2294 //! Apply breath velocity to instrument
2295 void startBlowing(MY_FLOAT amplitude
) { startBlowing ( amplitude
, m_rate
); } //chuck
2297 //! Apply breath velocity to instrument with given amplitude and rate of increase.
2298 void startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
);
2300 //! Decrease breath velocity with given rate of decrease.
2301 void stopBlowing(MY_FLOAT rate
);
2303 //! Start a note current frequency, given amplitude.
2304 void noteOn(MY_FLOAT amplitude
) { noteOn ( baseFrequency
, amplitude
); } //chuck
2306 //! Start a note with the given frequency and amplitude.
2307 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
2309 //! Stop a note with the given amplitude (speed of decay).
2310 void noteOff(MY_FLOAT amplitude
);
2312 //! Compute one output sample.
2315 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
2316 void controlChange(int number
, MY_FLOAT value
);
2318 public: // SWAP formerly protected
2327 MY_FLOAT maxPressure
;
2329 MY_FLOAT vibratoGain
;
2330 MY_FLOAT outputGain
;
2332 MY_FLOAT baseFrequency
; // chuck data
2340 /***************************************************/
2342 \brief STK reed table class.
2344 This class implements a simple one breakpoint,
2345 non-linear reed function, as described by
2346 Smith (1986). This function is based on a
2347 memoryless non-linear spring model of the reed
2348 (the reed mass is ignored) which saturates when
2349 the reed collides with the mouthpiece facing.
2351 See McIntyre, Schumacher, & Woodhouse (1983),
2352 Smith (1986), Hirschman, Cook, Scavone, and
2353 others for more information.
2355 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2357 /***************************************************/
2359 #if !defined(__REEDTABL_H)
2360 #define __REEDTABL_H
2363 class ReedTabl
: public Stk
2366 //! Default constructor.
2369 //! Class destructor.
2372 //! Set the table offset value.
2374 The table offset roughly corresponds to the size
2375 of the initial reed tip opening (a greater offset
2376 represents a smaller opening).
2378 void setOffset(MY_FLOAT aValue
);
2380 //! Set the table slope value.
2382 The table slope roughly corresponds to the reed
2383 stiffness (a greater slope represents a harder
2386 void setSlope(MY_FLOAT aValue
);
2388 //! Return the last output value.
2389 MY_FLOAT
lastOut() const;
2391 //! Return the function value for \e input.
2393 The function input represents the differential
2394 pressure across the reeds.
2396 MY_FLOAT
tick(MY_FLOAT input
);
2398 //! Take \e vectorSize inputs and return the corresponding function values in \e vector.
2399 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
2401 public: // SWAP formerly protected
2404 MY_FLOAT lastOutput
;
2413 /***************************************************/
2415 \brief STK one-zero filter class.
2417 This protected Filter subclass implements
2418 a one-zero digital filter. A method is
2419 provided for setting the zero position
2420 along the real axis of the z-plane while
2421 maintaining a constant filter gain.
2423 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2425 /***************************************************/
2427 #if !defined(__ONEZERO_H)
2431 class OneZero
: public Filter
// formerly protected Filter
2435 //! Default constructor creates a first-order low-pass filter.
2438 //! Overloaded constructor which sets the zero position during instantiation.
2439 OneZero(MY_FLOAT theZero
);
2441 //! Class destructor.
2444 //! Clears the internal state of the filter.
2447 //! Set the b[0] coefficient value.
2448 void setB0(MY_FLOAT b0
);
2450 //! Set the b[1] coefficient value.
2451 void setB1(MY_FLOAT b1
);
2453 //! Set the zero position in the z-plane.
2455 This method sets the zero position along the real-axis of the
2456 z-plane and normalizes the coefficients for a maximum gain of one.
2457 A positive zero value produces a high-pass filter, while a
2458 negative zero value produces a low-pass filter. This method does
2459 not affect the filter \e gain value.
2461 void setZero(MY_FLOAT theZero
);
2463 //! Set the filter gain.
2465 The gain is applied at the filter input and does not affect the
2466 coefficient values. The default gain value is 1.0.
2468 void setGain(MY_FLOAT theGain
);
2470 //! Return the current filter gain.
2471 MY_FLOAT
getGain(void) const;
2473 //! Return the last computed output value.
2474 MY_FLOAT
lastOut(void) const;
2476 //! Input one sample to the filter and return one output.
2477 MY_FLOAT
tick(MY_FLOAT sample
);
2479 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
2480 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
2488 /***************************************************/
2490 \brief STK clarinet physical model with one register hole and one tonehole.
2492 This class is based on the clarinet model,
2493 with the addition of a two-port register hole
2494 and a three-port dynamic tonehole
2495 implementation, as discussed by Scavone and
2498 In this implementation, the distances between
2499 the reed/register hole and tonehole/bell are
2500 fixed. As a result, both the tonehole and
2501 register hole will have variable influence on
2502 the playing frequency, which is dependent on
2503 the length of the air column. In addition,
2504 the highest playing freqeuency is limited by
2505 these fixed lengths.
2507 This is a digital waveguide model, making its
2508 use possibly subject to patents held by Stanford
2509 University, Yamaha, and others.
2511 Control Change Numbers:
2512 - Reed Stiffness = 2
2514 - Tonehole State = 11
2515 - Register State = 1
2516 - Breath Pressure = 128
2518 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2520 /***************************************************/
2522 #if !defined(__BLOWHOLE_H)
2523 #define __BLOWHOLE_H
2526 class BlowHole
: public Instrmnt
2529 //! Class constructor.
2530 BlowHole(MY_FLOAT lowestFrequency
);
2532 //! Class destructor.
2535 //! Reset and clear all internal state.
2538 //! Set instrument parameters for a particular frequency.
2539 void setFrequency(MY_FLOAT frequency
);
2541 //! Set the tonehole state (0.0 = closed, 1.0 = fully open).
2542 void setTonehole(MY_FLOAT newValue
);
2544 //! Set the register hole state (0.0 = closed, 1.0 = fully open).
2545 void setVent(MY_FLOAT newValue
);
2547 //! Apply breath velocity to instrument
2548 void startBlowing(MY_FLOAT amplitude
) { startBlowing ( amplitude
, m_rate
); } //chuck
2550 //! Apply breath pressure to instrument with given amplitude and rate of increase.
2551 void startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
);
2553 //! Decrease breath pressure with given rate of decrease.
2554 void stopBlowing(MY_FLOAT rate
);
2556 //! Start a note with the given frequency and amplitude.
2557 void noteOn( MY_FLOAT amplitude
) { noteOn ( m_frequency
, amplitude
); }
2558 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
2560 //! Stop a note with the given amplitude (speed of decay).
2561 void noteOff(MY_FLOAT amplitude
);
2563 //! Compute one output sample.
2566 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
2567 void controlChange(int number
, MY_FLOAT value
);
2569 public: // SWAP formerly protected
2578 ReedTabl
*reedTable
;
2591 MY_FLOAT outputGain
;
2593 MY_FLOAT vibratoGain
;
2602 /***************************************************/
2604 \brief STK one-pole filter class.
2606 This protected Filter subclass implements
2607 a one-pole digital filter. A method is
2608 provided for setting the pole position along
2609 the real axis of the z-plane while maintaining
2610 a constant peak filter gain.
2612 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2614 /***************************************************/
2616 #if !defined(__ONEPOLE_H)
2619 class OnePole
: public Filter
// formerly protected Filter
2623 //! Default constructor creates a first-order low-pass filter.
2626 //! Overloaded constructor which sets the pole position during instantiation.
2627 OnePole(MY_FLOAT thePole
);
2629 //! Class destructor.
2632 //! Clears the internal state of the filter.
2635 //! Set the b[0] coefficient value.
2636 void setB0(MY_FLOAT b0
);
2638 //! Set the a[1] coefficient value.
2639 void setA1(MY_FLOAT a1
);
2641 //! Set the pole position in the z-plane.
2643 This method sets the pole position along the real-axis of the
2644 z-plane and normalizes the coefficients for a maximum gain of one.
2645 A positive pole value produces a low-pass filter, while a negative
2646 pole value produces a high-pass filter. This method does not
2647 affect the filter \e gain value.
2649 void setPole(MY_FLOAT thePole
);
2651 //! Set the filter gain.
2653 The gain is applied at the filter input and does not affect the
2654 coefficient values. The default gain value is 1.0.
2656 void setGain(MY_FLOAT theGain
);
2658 //! Return the current filter gain.
2659 MY_FLOAT
getGain(void) const;
2661 //! Return the last computed output value.
2662 MY_FLOAT
lastOut(void) const;
2664 //! Input one sample to the filter and return one output.
2665 MY_FLOAT
tick(MY_FLOAT sample
);
2667 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
2668 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
2676 /***************************************************/
2678 \brief STK bowed string instrument class.
2680 This class implements a bowed string model, a
2681 la Smith (1986), after McIntyre, Schumacher,
2684 This is a digital waveguide model, making its
2685 use possibly subject to patents held by
2686 Stanford University, Yamaha, and others.
2688 Control Change Numbers:
2691 - Vibrato Frequency = 11
2695 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2697 /***************************************************/
2699 #if !defined(__BOWED_H)
2703 class Bowed
: public Instrmnt
2706 //! Class constructor, taking the lowest desired playing frequency.
2707 Bowed(MY_FLOAT lowestFrequency
);
2709 //! Class destructor.
2712 //! Reset and clear all internal state.
2715 //! Set instrument parameters for a particular frequency.
2716 void setFrequency(MY_FLOAT frequency
);
2718 //! Set vibrato gain.
2719 void setVibrato(MY_FLOAT gain
);
2721 void startBowing(MY_FLOAT amplitude
) { startBowing(amplitude
, m_rate
); }
2722 //! Apply breath pressure to instrument with given amplitude and rate of increase.
2723 void startBowing(MY_FLOAT amplitude
, MY_FLOAT rate
);
2725 //! Decrease breath pressure with given rate of decrease.
2726 void stopBowing(MY_FLOAT rate
);
2728 void noteOn(MY_FLOAT amplitude
) { noteOn ( m_frequency
, amplitude
); }
2729 //! Start a note with the given frequency and amplitude.
2730 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
2732 //! Stop a note with the given amplitude (speed of decay).
2733 void noteOff(MY_FLOAT amplitude
);
2735 //! Compute one output sample.
2738 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
2739 void controlChange(int number
, MY_FLOAT value
);
2741 public: // SWAP formerly protected
2745 DelayL
*bridgeDelay
;
2747 OnePole
*stringFilter
;
2751 MY_FLOAT maxVelocity
;
2753 MY_FLOAT vibratoGain
;
2763 /***************************************************/
2765 \brief STK allpass interpolating delay line class.
2767 This Delay subclass implements a fractional-
2768 length digital delay-line using a first-order
2769 allpass filter. A fixed maximum length
2770 of 4095 and a delay of 0.5 is set using the
2771 default constructor. Alternatively, the
2772 delay and maximum length can be set during
2773 instantiation with an overloaded constructor.
2775 An allpass filter has unity magnitude gain but
2776 variable phase delay properties, making it useful
2777 in achieving fractional delays without affecting
2778 a signal's frequency magnitude response. In
2779 order to achieve a maximally flat phase delay
2780 response, the minimum delay possible in this
2781 implementation is limited to a value of 0.5.
2783 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2785 /***************************************************/
2787 #if !defined(__DelayA_h)
2791 class DelayA
: public Delay
2795 //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay.
2798 //! Overloaded constructor which specifies the current and maximum delay-line lengths.
2800 DelayA(MY_FLOAT theDelay
, long maxDelay
);
2802 //! Class destructor.
2805 //! Clears the internal state of the delay line.
2808 //! Set the delay-line length
2810 The valid range for \e theDelay is from 0.5 to the maximum delay-line length.
2812 void setDelay(MY_FLOAT theDelay
);
2813 void set( MY_FLOAT delay
, long max
);
2815 //! Return the value which will be output by the next call to tick().
2817 This method is valid only for delay settings greater than zero!
2819 MY_FLOAT
nextOut(void);
2821 //! Input one sample to the delay-line and return one output.
2822 MY_FLOAT
tick(MY_FLOAT sample
);
2824 public: // SWAP formerly protected
2828 MY_FLOAT nextOutput
;
2837 /***************************************************/
2839 \brief STK simple brass instrument class.
2841 This class implements a simple brass instrument
2842 waveguide model, a la Cook (TBone, HosePlayer).
2844 This is a digital waveguide model, making its
2845 use possibly subject to patents held by
2846 Stanford University, Yamaha, and others.
2848 Control Change Numbers:
2851 - Vibrato Frequency = 11
2855 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2857 /***************************************************/
2859 #if !defined(__BRASS_H)
2863 class Brass
: public Instrmnt
2866 //! Class constructor, taking the lowest desired playing frequency.
2867 Brass(MY_FLOAT lowestFrequency
);
2869 //! Class destructor.
2872 //! Reset and clear all internal state.
2875 //! Set instrument parameters for a particular frequency.
2876 void setFrequency(MY_FLOAT frequency
);
2878 //! Set the lips frequency.
2879 void setLip(MY_FLOAT frequency
);
2881 //! Apply breath pressure to instrument with given amplitude and rate of increase.
2882 void startBlowing(MY_FLOAT amplitude
,MY_FLOAT rate
);
2884 //! Decrease breath pressure with given rate of decrease.
2885 void stopBlowing(MY_FLOAT rate
);
2887 //! Start a note with the given frequency and amplitude.
2888 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
2890 //! Stop a note with the given amplitude (speed of decay).
2891 void noteOff(MY_FLOAT amplitude
);
2893 //! Compute one output sample.
2896 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
2897 void controlChange(int number
, MY_FLOAT value
);
2899 public: // SWAP formerly protected
2907 MY_FLOAT slideTarget
;
2908 MY_FLOAT vibratoGain
;
2909 MY_FLOAT maxPressure
;
2918 /***************************************************/
2920 \brief STK chorus effect class.
2922 This class implements a chorus effect.
2924 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
2926 /***************************************************/
2928 #if !defined(__CHORUS_H)
2932 class Chorus
: public Stk
2935 //! Class constructor, taking the longest desired delay length.
2936 Chorus(MY_FLOAT baseDelay
);
2938 //! Class destructor.
2941 //! Reset and clear all internal state.
2944 //! Set modulation depth.
2945 void setModDepth(MY_FLOAT depth
);
2947 //! Set modulation frequency.
2948 void setModFrequency(MY_FLOAT frequency
);
2950 //! Set the mixture of input and processed levels in the output (0.0 = input only, 1.0 = processed only).
2951 void setEffectMix(MY_FLOAT mix
);
2953 //! Return the last output value.
2954 MY_FLOAT
lastOut() const;
2956 //! Return the last left output value.
2957 MY_FLOAT
lastOutLeft() const;
2959 //! Return the last right output value.
2960 MY_FLOAT
lastOutRight() const;
2962 //! Compute one output sample.
2963 MY_FLOAT
tick(MY_FLOAT input
);
2965 //! Take \e vectorSize inputs, compute the same number of outputs and return them in \e vector.
2966 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
2968 public: // SWAP formerly protected
2969 DelayL
*delayLine
[2];
2971 MY_FLOAT baseLength
;
2973 MY_FLOAT lastOutput
[2];
2984 /***************************************************/
2986 \brief STK clarinet physical model class.
2988 This class implements a simple clarinet
2989 physical model, as discussed by Smith (1986),
2990 McIntyre, Schumacher, Woodhouse (1983), and
2993 This is a digital waveguide model, making its
2994 use possibly subject to patents held by Stanford
2995 University, Yamaha, and others.
2997 Control Change Numbers:
2998 - Reed Stiffness = 2
3000 - Vibrato Frequency = 11
3002 - Breath Pressure = 128
3004 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3006 /***************************************************/
3008 #if !defined(__CLARINET_H)
3009 #define __CLARINET_H
3012 class Clarinet
: public Instrmnt
3015 //! Class constructor, taking the lowest desired playing frequency.
3016 Clarinet(MY_FLOAT lowestFrequency
);
3018 //! Class destructor.
3021 //! Reset and clear all internal state.
3024 //! Set instrument parameters for a particular frequency.
3025 void setFrequency(MY_FLOAT frequency
);
3027 //! Apply breath pressure to instrument with given amplitude and rate of increase.
3028 void startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
);
3030 //! Decrease breath pressure with given rate of decrease.
3031 void stopBlowing(MY_FLOAT rate
);
3033 //! Start a note with the given frequency and amplitude.
3034 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
3036 //! Stop a note with the given amplitude (speed of decay).
3037 void noteOff(MY_FLOAT amplitude
);
3039 //! Compute one output sample.
3042 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
3043 void controlChange(int number
, MY_FLOAT value
);
3045 public: // SWAP formerly protected
3047 ReedTabl
*reedTable
;
3053 MY_FLOAT outputGain
;
3055 MY_FLOAT vibratoGain
;
3064 /***************************************************/
3066 \brief STK drum sample player class.
3068 This class implements a drum sampling
3069 synthesizer using WvIn objects and one-pole
3070 filters. The drum rawwave files are sampled
3071 at 22050 Hz, but will be appropriately
3072 interpolated for other sample rates. You can
3073 specify the maximum polyphony (maximum number
3074 of simultaneous voices) via a #define in the
3077 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3079 /***************************************************/
3081 #if !defined(__DRUMMER_H)
3085 #define DRUM_NUMWAVES 11
3086 #define DRUM_POLYPHONY 4
3088 class Drummer
: public Instrmnt
3091 //! Class constructor.
3094 //! Class destructor.
3097 //! Start a note with the given drum type and amplitude.
3099 Use general MIDI drum instrument numbers, converted to
3100 frequency values as if MIDI note numbers, to select a
3101 particular instrument.
3103 void noteOn(MY_FLOAT instrument
, MY_FLOAT amplitude
);
3105 //! Stop a note with the given amplitude (speed of decay).
3106 void noteOff(MY_FLOAT amplitude
);
3108 //! Compute one output sample.
3111 public: // SWAP formerly protected
3112 WvIn
*waves
[DRUM_POLYPHONY
];
3113 OnePole
*filters
[DRUM_POLYPHONY
];
3114 int sounding
[DRUM_POLYPHONY
];
3124 /***************************************************/
3126 \brief STK echo effect class.
3128 This class implements a echo effect.
3130 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3132 /***************************************************/
3134 #if !defined(__ECHO_H)
3138 class Echo
: public Stk
3141 //! Class constructor, taking the longest desired delay length.
3142 Echo(MY_FLOAT longestDelay
);
3144 //! Class destructor.
3147 //! Reset and clear all internal state.
3150 //! Set the delay line length in samples.
3151 void setDelay(MY_FLOAT delay
);
3152 void set(MY_FLOAT max
);
3153 MY_FLOAT
getDelay();
3155 //! Set the mixture of input and processed levels in the output (0.0 = input only, 1.0 = processed only).
3156 void setEffectMix(MY_FLOAT mix
);
3158 //! Return the last output value.
3159 MY_FLOAT
lastOut() const;
3161 //! Compute one output sample.
3162 MY_FLOAT
tick(MY_FLOAT input
);
3164 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
3165 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
3170 MY_FLOAT lastOutput
;
3181 /***************************************************/
3183 \brief STK singing FM synthesis instrument.
3185 This class implements 3 carriers and a common
3186 modulator, also referred to as algorithm 6 of
3196 Control Change Numbers:
3201 - ADSR 2 & 4 Target = 128
3203 The basic Chowning/Stanford FM patent expired
3204 in 1995, but there exist follow-on patents,
3205 mostly assigned to Yamaha. If you are of the
3206 type who should worry about this (making
3209 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3211 /***************************************************/
3213 #if !defined(__FMVOICES_H)
3214 #define __FMVOICES_H
3217 class FMVoices
: public FM
3220 //! Class constructor.
3223 //! Class destructor.
3226 //! Set instrument parameters for a particular frequency.
3227 virtual void setFrequency(MY_FLOAT frequency
);
3229 //! Start a note with the given frequency and amplitude.
3230 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
3231 void noteOn( MY_FLOAT amplitude
) { noteOn(baseFrequency
, amplitude
); }
3233 //! Compute one output sample.
3236 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
3237 virtual void controlChange(int number
, MY_FLOAT value
);
3239 public: // SWAP formerly protected
3250 /***************************************************/
3252 \brief STK flute physical model class.
3254 This class implements a simple flute
3255 physical model, as discussed by Karjalainen,
3256 Smith, Waryznyk, etc. The jet model uses
3257 a polynomial, a la Cook.
3259 This is a digital waveguide model, making its
3260 use possibly subject to patents held by Stanford
3261 University, Yamaha, and others.
3263 Control Change Numbers:
3266 - Vibrato Frequency = 11
3268 - Breath Pressure = 128
3270 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3272 /***************************************************/
3274 #if !defined(__FLUTE_H)
3278 class Flute
: public Instrmnt
3281 //! Class constructor, taking the lowest desired playing frequency.
3282 Flute(MY_FLOAT lowestFrequency
);
3284 //! Class destructor.
3287 //! Reset and clear all internal state.
3290 //! Set instrument parameters for a particular frequency.
3291 void setFrequency(MY_FLOAT frequency
);
3293 //! Set the reflection coefficient for the jet delay (-1.0 - 1.0).
3294 void setJetReflection(MY_FLOAT coefficient
);
3296 //! Set the reflection coefficient for the air column delay (-1.0 - 1.0).
3297 void setEndReflection(MY_FLOAT coefficient
);
3299 //! Set the length of the jet delay in terms of a ratio of jet delay to air column delay lengths.
3300 void setJetDelay(MY_FLOAT aRatio
);
3302 //! Apply breath velocity to instrument with given amplitude and rate of increase.
3303 void startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
);
3305 //! Decrease breath velocity with given rate of decrease.
3306 void stopBlowing(MY_FLOAT rate
);
3308 //! Start a note with the given frequency and amplitude.
3309 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
3311 //! Stop a note with the given amplitude (speed of decay).
3312 void noteOff(MY_FLOAT amplitude
);
3314 //! Compute one output sample.
3317 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
3318 void controlChange(int number
, MY_FLOAT value
);
3320 public: // SWAP formerly protected
3330 MY_FLOAT lastFrequency
;
3331 MY_FLOAT maxPressure
;
3332 MY_FLOAT jetReflection
;
3333 MY_FLOAT endReflection
;
3335 MY_FLOAT vibratoGain
;
3336 MY_FLOAT outputGain
;
3346 /***************************************************/
3348 \brief STK sweepable formant filter class.
3350 This public BiQuad filter subclass implements
3351 a formant (resonance) which can be "swept"
3352 over time from one frequency setting to another.
3353 It provides methods for controlling the sweep
3354 rate and target frequency.
3356 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3358 /***************************************************/
3360 #if !defined(__FORMSWEP_H)
3361 #define __FORMSWEP_H
3364 class FormSwep
: public BiQuad
3368 //! Default constructor creates a second-order pass-through filter.
3371 //! Class destructor.
3374 //! Sets the filter coefficients for a resonance at \e frequency (in Hz).
3376 This method determines the filter coefficients corresponding to
3377 two complex-conjugate poles with the given \e frequency (in Hz)
3378 and \e radius from the z-plane origin. The filter zeros are
3379 placed at z = 1, z = -1, and the coefficients are then normalized to
3380 produce a constant unity gain (independent of the filter \e gain
3381 parameter). The resulting filter frequency response has a
3382 resonance at the given \e frequency. The closer the poles are to
3383 the unit-circle (\e radius close to one), the narrower the
3384 resulting resonance width.
3386 void setResonance(MY_FLOAT aFrequency
, MY_FLOAT aRadius
);
3388 //! Set both the current and target resonance parameters.
3389 void setStates(MY_FLOAT aFrequency
, MY_FLOAT aRadius
, MY_FLOAT aGain
= 1.0);
3391 //! Set target resonance parameters.
3392 void setTargets(MY_FLOAT aFrequency
, MY_FLOAT aRadius
, MY_FLOAT aGain
= 1.0);
3394 //! Set the sweep rate (between 0.0 - 1.0).
3396 The formant parameters are varied in increments of the
3397 sweep rate between their current and target values.
3398 A sweep rate of 1.0 will produce an immediate change in
3399 resonance parameters from their current values to the
3400 target values. A sweep rate of 0.0 will produce no
3401 change in resonance parameters.
3403 void setSweepRate(MY_FLOAT aRate
);
3405 //! Set the sweep rate in terms of a time value in seconds.
3407 This method adjusts the sweep rate based on a
3408 given time for the formant parameters to reach
3409 their target values.
3411 void setSweepTime(MY_FLOAT aTime
);
3413 //! Input one sample to the filter and return one output.
3414 MY_FLOAT
tick(MY_FLOAT sample
);
3416 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
3417 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
3419 public: // SWAP formerly protected
3423 MY_FLOAT startFrequency
;
3424 MY_FLOAT startRadius
;
3426 MY_FLOAT targetFrequency
;
3427 MY_FLOAT targetRadius
;
3428 MY_FLOAT targetGain
;
3429 MY_FLOAT deltaFrequency
;
3430 MY_FLOAT deltaRadius
;
3432 MY_FLOAT sweepState
;
3442 /***************************************************/
3444 \brief STK heavy metal FM synthesis instrument.
3446 This class implements 3 cascade operators with
3447 feedback modulation, also referred to as
3448 algorithm 3 of the TX81Z.
3451 Algorithm 3 is : 4--\
3452 3-->2-- + -->1-->Out
3455 Control Change Numbers:
3456 - Total Modulator Index = 2
3457 - Modulator Crossfade = 4
3460 - ADSR 2 & 4 Target = 128
3462 The basic Chowning/Stanford FM patent expired
3463 in 1995, but there exist follow-on patents,
3464 mostly assigned to Yamaha. If you are of the
3465 type who should worry about this (making
3468 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3470 /***************************************************/
3472 #if !defined(__HEVYMETL_H)
3473 #define __HEVYMETL_H
3476 class HevyMetl
: public FM
3479 //! Class constructor.
3482 //! Class destructor.
3485 //! Start a note with the given frequency and amplitude.
3486 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
3487 void noteOn( MY_FLOAT amplitude
) { noteOn(baseFrequency
, amplitude
); }
3489 //! Compute one output sample.
3498 /***************************************************/
3500 \brief STK abstract reverberator parent class.
3502 This class provides common functionality for
3503 STK reverberator subclasses.
3505 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3507 /***************************************************/
3510 #if !defined(__REVERB_H)
3513 class Reverb
: public Stk
3516 //! Class constructor.
3519 //! Class destructor.
3522 //! Reset and clear all internal state.
3523 virtual void clear() = 0;
3525 //! Set the mixture of input and "reverberated" levels in the output (0.0 = input only, 1.0 = reverb only).
3526 void setEffectMix(MY_FLOAT mix
);
3528 //! Return the last output value.
3529 MY_FLOAT
lastOut() const;
3531 //! Return the last left output value.
3532 MY_FLOAT
lastOutLeft() const;
3534 //! Return the last right output value.
3535 MY_FLOAT
lastOutRight() const;
3537 //! Abstract tick function ... must be implemented in subclasses.
3538 virtual MY_FLOAT
tick(MY_FLOAT input
) = 0;
3540 //! Take \e vectorSize inputs, compute the same number of outputs and return them in \e vector.
3541 virtual MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
3543 public: // SWAP formerly protected
3545 // Returns true if argument value is prime.
3546 bool isPrime(int number
);
3548 MY_FLOAT lastOutput
[2];
3553 #endif // defined(__REVERB_H)
3559 /***************************************************/
3561 \brief John Chowning's reverberator class.
3563 This class is derived from the CLM JCRev
3564 function, which is based on the use of
3565 networks of simple allpass and comb delay
3566 filters. This class implements three series
3567 allpass units, followed by four parallel comb
3568 filters, and two decorrelation delay lines in
3569 parallel at the output.
3571 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3573 /***************************************************/
3575 #if !defined(__JCREV_H)
3579 class JCRev
: public Reverb
3582 //! Class constructor taking a T60 decay time argument.
3583 JCRev(MY_FLOAT T60
);
3585 //! Class destructor.
3588 //! Reset and clear all internal state.
3591 //! Compute one output sample.
3592 MY_FLOAT
tick(MY_FLOAT input
);
3594 public: // SWAP formerly protected
3595 Delay
*allpassDelays
[3];
3596 Delay
*combDelays
[4];
3597 Delay
*outLeftDelay
;
3598 Delay
*outRightDelay
;
3599 MY_FLOAT allpassCoefficient
;
3600 MY_FLOAT combCoefficient
[4];
3610 /***************************************************/
3612 \brief STK enhanced plucked string model class.
3614 This class implements an enhanced two-string,
3615 plucked physical model, a la Jaffe-Smith,
3618 PluckTwo is an abstract class, with no excitation
3619 specified. Therefore, it can't be directly
3622 This is a digital waveguide model, making its
3623 use possibly subject to patents held by
3624 Stanford University, Yamaha, and others.
3626 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3628 /***************************************************/
3630 #if !defined(__PLUCKTWO_H)
3631 #define __PLUCKTWO_H
3634 class PluckTwo
: public Instrmnt
3637 //! Class constructor, taking the lowest desired playing frequency.
3638 PluckTwo(MY_FLOAT lowestFrequency
);
3640 //! Class destructor.
3641 virtual ~PluckTwo();
3643 //! Reset and clear all internal state.
3646 //! Set instrument parameters for a particular frequency.
3647 virtual void setFrequency(MY_FLOAT frequency
);
3649 //! Detune the two strings by the given factor. A value of 1.0 produces unison strings.
3650 void setDetune(MY_FLOAT detune
);
3652 //! Efficient combined setting of frequency and detuning.
3653 void setFreqAndDetune(MY_FLOAT frequency
, MY_FLOAT detune
);
3655 //! Set the pluck or "excitation" position along the string (0.0 - 1.0).
3656 void setPluckPosition(MY_FLOAT position
);
3658 //! Set the base loop gain.
3660 The actual loop gain is set according to the frequency.
3661 Because of high-frequency loop filter roll-off, higher
3662 frequency settings have greater loop gains.
3664 void setBaseLoopGain(MY_FLOAT aGain
);
3666 //! Stop a note with the given amplitude (speed of decay).
3667 virtual void noteOff(MY_FLOAT amplitude
);
3669 //! Virtual (abstract) tick function is implemented by subclasses.
3670 virtual MY_FLOAT
tick() = 0;
3672 public: // SWAP formerly protected
3680 MY_FLOAT baseLoopGain
;
3681 MY_FLOAT lastFrequency
;
3682 MY_FLOAT lastLength
;
3684 MY_FLOAT pluckAmplitude
;
3685 MY_FLOAT pluckPosition
;
3694 /***************************************************/
3696 \brief STK mandolin instrument model class.
3698 This class inherits from PluckTwo and uses
3699 "commuted synthesis" techniques to model a
3700 mandolin instrument.
3702 This is a digital waveguide model, making its
3703 use possibly subject to patents held by
3704 Stanford University, Yamaha, and others.
3705 Commuted Synthesis, in particular, is covered
3706 by patents, granted, pending, and/or
3707 applied-for. All are assigned to the Board of
3708 Trustees, Stanford University. For
3709 information, contact the Office of Technology
3710 Licensing, Stanford University.
3712 Control Change Numbers:
3714 - Pluck Position = 4
3715 - String Sustain = 11
3716 - String Detuning = 1
3717 - Microphone Position = 128
3719 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3721 /***************************************************/
3723 #if !defined(__MANDOLIN_H)
3724 #define __MANDOLIN_H
3727 class Mandolin
: public PluckTwo
3730 //! Class constructor, taking the lowest desired playing frequency.
3731 Mandolin(MY_FLOAT lowestFrequency
);
3733 //! Class destructor.
3734 virtual ~Mandolin();
3736 //! Pluck the strings with the given amplitude (0.0 - 1.0) using the current frequency.
3737 void pluck(MY_FLOAT amplitude
);
3739 //! Pluck the strings with the given amplitude (0.0 - 1.0) and position (0.0 - 1.0).
3740 void pluck(MY_FLOAT amplitude
,MY_FLOAT position
);
3742 //! Start a note with the given frequency and amplitude (0.0 - 1.0).
3743 virtual void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
3745 //! Set the body size (a value of 1.0 produces the "default" size).
3746 void setBodySize(MY_FLOAT size
);
3748 //! Compute one output sample.
3749 virtual MY_FLOAT
tick();
3751 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
3752 virtual void controlChange(int number
, MY_FLOAT value
);
3754 public: // SWAP formerly protected
3755 WvIn
*soundfile
[12];
3756 MY_FLOAT directBody
;
3760 MY_FLOAT m_bodySize
;
3761 MY_FLOAT m_stringDamping
;
3762 MY_FLOAT m_stringDetune
;
3770 /***************************************************/
3772 \brief Two-dimensional rectilinear waveguide mesh class.
3774 This class implements a rectilinear,
3775 two-dimensional digital waveguide mesh
3776 structure. For details, see Van Duyne and
3777 Smith, "Physical Modeling with the 2-D Digital
3778 Waveguide Mesh", Proceedings of the 1993
3779 International Computer Music Conference.
3781 This is a digital waveguide model, making its
3782 use possibly subject to patents held by Stanford
3783 University, Yamaha, and others.
3785 Control Change Numbers:
3789 - X-Y Input Position = 1
3791 by Julius Smith, 2000 - 2002.
3792 Revised by Gary Scavone for STK, 2002.
3794 /***************************************************/
3796 #if !defined(__MESH2D_H)
3800 #define NXMAX ((short)(12))
3801 #define NYMAX ((short)(12))
3803 class Mesh2D
: public Instrmnt
3806 //! Class constructor, taking the x and y dimensions in samples.
3807 Mesh2D(short nX
, short nY
);
3809 //! Class destructor.
3812 //! Reset and clear all internal state.
3815 //! Set the x dimension size in samples.
3816 void setNX(short lenX
);
3818 //! Set the y dimension size in samples.
3819 void setNY(short lenY
);
3821 //! Set the x, y input position on a 0.0 - 1.0 scale.
3822 void setInputPosition(MY_FLOAT xFactor
, MY_FLOAT yFactor
);
3824 //! Set the loss filters gains (0.0 - 1.0).
3825 void setDecay(MY_FLOAT decayFactor
);
3827 //! Impulse the mesh with the given amplitude (frequency ignored).
3828 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
3830 //! Stop a note with the given amplitude (speed of decay) ... currently ignored.
3831 void noteOff(MY_FLOAT amplitude
);
3833 //! Calculate and return the signal energy stored in the mesh.
3836 //! Compute one output sample, without adding energy to the mesh.
3839 //! Input a sample to the mesh and compute one output sample.
3840 MY_FLOAT
tick(MY_FLOAT input
);
3842 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
3843 void controlChange(int number
, MY_FLOAT value
);
3845 public: // SWAP formerly protected
3852 short xInput
, yInput
;
3853 OnePole
*filterX
[NXMAX
];
3854 OnePole
*filterY
[NYMAX
];
3855 MY_FLOAT v
[NXMAX
-1][NYMAX
-1]; // junction velocities
3856 MY_FLOAT vxp
[NXMAX
][NYMAX
]; // positive-x velocity wave
3857 MY_FLOAT vxm
[NXMAX
][NYMAX
]; // negative-x velocity wave
3858 MY_FLOAT vyp
[NXMAX
][NYMAX
]; // positive-y velocity wave
3859 MY_FLOAT vym
[NXMAX
][NYMAX
]; // negative-y velocity wave
3861 // Alternate buffers
3862 MY_FLOAT vxp1
[NXMAX
][NYMAX
]; // positive-x velocity wave
3863 MY_FLOAT vxm1
[NXMAX
][NYMAX
]; // negative-x velocity wave
3864 MY_FLOAT vyp1
[NXMAX
][NYMAX
]; // positive-y velocity wave
3865 MY_FLOAT vym1
[NXMAX
][NYMAX
]; // negative-y velocity wave
3867 int counter
; // time in samples
3877 /***************************************************/
3879 \brief STK resonance model instrument.
3881 This class contains an excitation wavetable,
3882 an envelope, an oscillator, and N resonances
3883 (non-sweeping BiQuad filters), where N is set
3884 during instantiation.
3886 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3888 /***************************************************/
3890 #if !defined(__MODAL_H)
3894 class Modal
: public Instrmnt
3897 //! Class constructor, taking the desired number of modes to create.
3898 Modal( int modes
= 4 );
3900 //! Class destructor.
3903 //! Reset and clear all internal state.
3906 //! Set instrument parameters for a particular frequency.
3907 virtual void setFrequency(MY_FLOAT frequency
);
3909 //! Set the ratio and radius for a specified mode filter.
3910 void setRatioAndRadius(int modeIndex
, MY_FLOAT ratio
, MY_FLOAT radius
);
3912 //! Set the master gain.
3913 void setMasterGain(MY_FLOAT aGain
);
3915 //! Set the direct gain.
3916 void setDirectGain(MY_FLOAT aGain
);
3918 //! Set the gain for a specified mode filter.
3919 void setModeGain(int modeIndex
, MY_FLOAT gain
);
3921 //! Initiate a strike with the given amplitude (0.0 - 1.0).
3922 virtual void strike(MY_FLOAT amplitude
);
3924 //! Damp modes with a given decay factor (0.0 - 1.0).
3925 void damp(MY_FLOAT amplitude
);
3927 //! Start a note with the given frequency and amplitude.
3928 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
3930 //! Stop a note with the given amplitude (speed of decay).
3931 void noteOff(MY_FLOAT amplitude
);
3933 //! Compute one output sample.
3934 virtual MY_FLOAT
tick();
3936 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
3937 virtual void controlChange(int number
, MY_FLOAT value
) = 0;
3939 public: // SWAP formerly protected
3946 MY_FLOAT vibratoGain
;
3947 MY_FLOAT masterGain
;
3948 MY_FLOAT directGain
;
3949 MY_FLOAT stickHardness
;
3950 MY_FLOAT strikePosition
;
3951 MY_FLOAT baseFrequency
;
3962 /***************************************************/
3964 \brief STK resonant bar instrument class.
3966 This class implements a number of different
3967 struck bar instruments. It inherits from the
3970 Control Change Numbers:
3971 - Stick Hardness = 2
3972 - Stick Position = 4
3974 - Vibrato Frequency = 7
3976 - Modal Presets = 16
3987 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
3989 /***************************************************/
3991 #if !defined(__MODALBAR_H)
3992 #define __MODALBAR_H
3995 class ModalBar
: public Modal
3998 //! Class constructor.
4001 //! Class destructor.
4004 //! Set stick hardness (0.0 - 1.0).
4005 void setStickHardness(MY_FLOAT hardness
);
4007 //! Set stick position (0.0 - 1.0).
4008 void setStrikePosition(MY_FLOAT position
);
4010 //! Select a bar preset (currently modulo 9).
4011 void setPreset(int preset
);
4013 //! Set the modulation (vibrato) depth.
4014 void setModulationDepth(MY_FLOAT mDepth
);
4016 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
4017 void controlChange(int number
, MY_FLOAT value
);
4025 /***************************************************/
4027 \brief STK sub-sampled noise generator.
4029 Generates a new random number every "rate" ticks
4030 using the C rand() function. The quality of the
4031 rand() function varies from one OS to another.
4033 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4035 /***************************************************/
4037 #if !defined(__SUBNOISE_H)
4038 #define __SUBNOISE_H
4041 class SubNoise
: public Noise
4045 //! Default constructor sets sub-sample rate to 16.
4046 SubNoise(int subRate
= 16);
4048 //! Class destructor.
4051 //! Return the current sub-sampling rate.
4052 int subRate(void) const;
4054 //! Set the sub-sampling rate.
4055 void setRate(int subRate
);
4057 //! Return a sub-sampled random number between -1.0 and 1.0.
4060 public: // SWAP formerly protected
4071 /***************************************************/
4073 \brief STK periodic/random modulator.
4075 This class combines random and periodic
4076 modulations to give a nice, natural human
4077 modulation function.
4079 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4081 /***************************************************/
4083 #if !defined(__MODULATE_H)
4084 #define __MODULATE_H
4087 class Modulate
: public Stk
4090 //! Class constructor.
4093 //! Class destructor.
4096 //! Reset internal state.
4099 //! Set the periodic (vibrato) rate or frequency in Hz.
4100 void setVibratoRate(MY_FLOAT aRate
);
4102 //! Set the periodic (vibrato) gain.
4103 void setVibratoGain(MY_FLOAT aGain
);
4105 //! Set the random modulation gain.
4106 void setRandomGain(MY_FLOAT aGain
);
4108 //! Compute one output sample.
4111 //! Return \e vectorSize outputs in \e vector.
4112 virtual MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
4114 //! Return the last computed output value.
4115 MY_FLOAT
lastOut() const;
4117 public: // SWAP formerly protected
4121 MY_FLOAT vibratoGain
;
4122 MY_FLOAT randomGain
;
4123 MY_FLOAT lastOutput
;
4132 /***************************************************/
4134 \brief STK sampling synthesis abstract base class.
4136 This instrument contains up to 5 attack waves,
4137 5 looped waves, and an ADSR envelope.
4139 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4141 /***************************************************/
4143 #if !defined(__SAMPLER_H)
4147 class Sampler
: public Instrmnt
4150 //! Default constructor.
4153 //! Class destructor.
4156 //! Reset and clear all internal state.
4159 //! Set instrument parameters for a particular frequency.
4160 virtual void setFrequency(MY_FLOAT frequency
) = 0;
4162 //! Initiate the envelopes with a key-on event and reset the attack waves.
4165 //! Signal a key-off event to the envelopes.
4168 //! Stop a note with the given amplitude (speed of decay).
4169 virtual void noteOff(MY_FLOAT amplitude
);
4171 //! Compute one output sample.
4172 virtual MY_FLOAT
tick();
4174 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
4175 virtual void controlChange(int number
, MY_FLOAT value
) = 0;
4177 public: // SWAP formerly protected
4182 MY_FLOAT baseFrequency
;
4183 MY_FLOAT attackRatios
[5];
4184 MY_FLOAT loopRatios
[5];
4185 MY_FLOAT attackGain
;
4196 /***************************************************/
4198 \brief STK moog-like swept filter sampling synthesis class.
4200 This instrument uses one attack wave, one
4201 looped wave, and an ADSR envelope (inherited
4202 from the Sampler class) and adds two sweepable
4203 formant (FormSwep) filters.
4205 Control Change Numbers:
4207 - Filter Sweep Rate = 4
4208 - Vibrato Frequency = 11
4212 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4214 /***************************************************/
4216 #if !defined(__MOOG_H)
4220 class Moog
: public Sampler
4223 //! Class constructor.
4226 //! Class destructor.
4229 //! Set instrument parameters for a particular frequency.
4230 virtual void setFrequency(MY_FLOAT frequency
);
4232 //! Start a note with the given frequency and amplitude.
4233 virtual void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
4234 virtual void noteOn(MY_FLOAT amplitude
); //CHUCK! note start note with current frequency
4236 //! Set the modulation (vibrato) speed in Hz.
4237 void setModulationSpeed(MY_FLOAT mSpeed
);
4239 //! Set the modulation (vibrato) depth.
4240 void setModulationDepth(MY_FLOAT mDepth
);
4242 //! Compute one output sample.
4243 virtual MY_FLOAT
tick();
4245 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
4246 virtual void controlChange(int number
, MY_FLOAT value
);
4248 public: // SWAP formerly protected
4249 FormSwep
*filters
[2];
4252 MY_FLOAT filterRate
;
4261 /***************************************************/
4263 \brief CCRMA's NRev reverberator class.
4265 This class is derived from the CLM NRev
4266 function, which is based on the use of
4267 networks of simple allpass and comb delay
4268 filters. This particular arrangement consists
4269 of 6 comb filters in parallel, followed by 3
4270 allpass filters, a lowpass filter, and another
4271 allpass in series, followed by two allpass
4272 filters in parallel with corresponding right
4275 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4277 /***************************************************/
4279 #if !defined(__NREV_H)
4283 class NRev
: public Reverb
4286 //! Class constructor taking a T60 decay time argument.
4289 //! Class destructor.
4292 //! Reset and clear all internal state.
4295 //! Compute one output sample.
4296 MY_FLOAT
tick(MY_FLOAT input
);
4298 public: // SWAP formerly protected
4299 Delay
*allpassDelays
[8];
4300 Delay
*combDelays
[6];
4301 MY_FLOAT allpassCoefficient
;
4302 MY_FLOAT combCoefficient
[6];
4303 MY_FLOAT lowpassState
;
4313 /***************************************************/
4315 \brief Perry's simple reverberator class.
4317 This class is based on some of the famous
4318 Stanford/CCRMA reverbs (NRev, KipRev), which
4319 were based on the Chowning/Moorer/Schroeder
4320 reverberators using networks of simple allpass
4321 and comb delay filters. This class implements
4322 two series allpass units and two parallel comb
4325 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4327 /***************************************************/
4329 #if !defined(__PRCREV_H)
4333 class PRCRev
: public Reverb
4336 //! Class constructor taking a T60 decay time argument.
4337 PRCRev(MY_FLOAT T60
);
4339 //! Class destructor.
4342 //! Reset and clear all internal state.
4345 //! Compute one output sample.
4346 MY_FLOAT
tick(MY_FLOAT input
);
4348 public: // SWAP formerly protected
4349 Delay
*allpassDelays
[2];
4350 Delay
*combDelays
[2];
4351 MY_FLOAT allpassCoefficient
;
4352 MY_FLOAT combCoefficient
[2];
4362 /***************************************************/
4364 \brief STK percussive flute FM synthesis instrument.
4366 This class implements algorithm 4 of the TX81Z.
4369 Algorithm 4 is : 4->3--\
4373 Control Change Numbers:
4374 - Total Modulator Index = 2
4375 - Modulator Crossfade = 4
4378 - ADSR 2 & 4 Target = 128
4380 The basic Chowning/Stanford FM patent expired
4381 in 1995, but there exist follow-on patents,
4382 mostly assigned to Yamaha. If you are of the
4383 type who should worry about this (making
4386 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4388 /***************************************************/
4390 #if !defined(__PERCFLUT_H)
4391 #define __PERCFLUT_H
4394 class PercFlut
: public FM
4397 //! Class constructor.
4400 //! Class destructor.
4403 //! Set instrument parameters for a particular frequency.
4404 void setFrequency(MY_FLOAT frequency
);
4406 //! Start a note with the given frequency and amplitude.
4407 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
4408 void noteOn( MY_FLOAT amplitude
) { noteOn(baseFrequency
, amplitude
); }
4410 //! Compute one output sample.
4419 /***************************************************/
4421 \brief STK phonemes table.
4423 This class does nothing other than declare a
4424 set of 32 static phoneme formant parameters
4425 and provide access to those values.
4427 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4429 /***************************************************/
4431 #if !defined(__PHONEMES_H)
4432 #define __PHONEMES_H
4442 //! Returns the phoneme name for the given index (0-31).
4443 static const char *name( unsigned int index
);
4445 //! Returns the voiced component gain for the given phoneme index (0-31).
4446 static MY_FLOAT
voiceGain( unsigned int index
);
4448 //! Returns the unvoiced component gain for the given phoneme index (0-31).
4449 static MY_FLOAT
noiseGain( unsigned int index
);
4451 //! Returns the formant frequency for the given phoneme index (0-31) and partial (0-3).
4452 static MY_FLOAT
formantFrequency( unsigned int index
, unsigned int partial
);
4454 //! Returns the formant radius for the given phoneme index (0-31) and partial (0-3).
4455 static MY_FLOAT
formantRadius( unsigned int index
, unsigned int partial
);
4457 //! Returns the formant gain for the given phoneme index (0-31) and partial (0-3).
4458 static MY_FLOAT
formantGain( unsigned int index
, unsigned int partial
);
4460 public: // SWAP formerly private
4462 static const char phonemeNames
[][4];
4463 static const MY_FLOAT phonemeGains
[][2];
4464 static const MY_FLOAT phonemeParameters
[][4][3];
4473 /***************************************************/
4475 \brief STK simple pitch shifter effect class.
4477 This class implements a simple pitch shifter
4480 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4482 /***************************************************/
4484 #if !defined(__PITSHIFT_H)
4485 #define __PITSHIFT_H
4488 class PitShift
: public Stk
4491 //! Class constructor.
4494 //! Class destructor.
4497 //! Reset and clear all internal state.
4500 //! Set the pitch shift factor (1.0 produces no shift).
4501 void setShift(MY_FLOAT shift
);
4503 //! Set the mixture of input and processed levels in the output (0.0 = input only, 1.0 = processed only).
4504 void setEffectMix(MY_FLOAT mix
);
4506 //! Return the last output value.
4507 MY_FLOAT
lastOut() const;
4509 //! Compute one output sample.
4510 MY_FLOAT
tick(MY_FLOAT input
);
4512 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
4513 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
4515 public: // SWAP formerly protected
4516 DelayL
*delayLine
[2];
4517 MY_FLOAT lastOutput
;
4531 /***************************************************/
4533 \brief STK plucked string model class.
4535 This class implements a simple plucked string
4536 physical model based on the Karplus-Strong
4539 This is a digital waveguide model, making its
4540 use possibly subject to patents held by
4541 Stanford University, Yamaha, and others.
4542 There exist at least two patents, assigned to
4543 Stanford, bearing the names of Karplus and/or
4546 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4548 /***************************************************/
4550 #if !defined(__PLUCKED_H)
4554 class Plucked
: public Instrmnt
4557 //! Class constructor, taking the lowest desired playing frequency.
4558 Plucked(MY_FLOAT lowestFrequency
);
4560 //! Class destructor.
4563 //! Reset and clear all internal state.
4566 //! Set instrument parameters for a particular frequency.
4567 virtual void setFrequency(MY_FLOAT frequency
);
4569 //! Pluck the string with the given amplitude using the current frequency.
4570 void pluck(MY_FLOAT amplitude
);
4572 //! Start a note with the given frequency and amplitude.
4573 virtual void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
4575 //! Stop a note with the given amplitude (speed of decay).
4576 virtual void noteOff(MY_FLOAT amplitude
);
4578 //! Compute one output sample.
4579 virtual MY_FLOAT
tick();
4581 public: // SWAP formerly protected
4583 OneZero
*loopFilter
;
4584 OnePole
*pickFilter
;
4597 /***************************************************/
4599 \brief STK noise driven formant filter.
4601 This instrument contains a noise source, which
4602 excites a biquad resonance filter, with volume
4603 controlled by an ADSR.
4605 Control Change Numbers:
4606 - Resonance Frequency (0-Nyquist) = 2
4608 - Notch Frequency (0-Nyquist) = 11
4610 - Envelope Gain = 128
4612 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4614 /***************************************************/
4616 #if !defined(__RESONATE_H)
4617 #define __RESONATE_H
4620 class Resonate
: public Instrmnt
4623 //! Class constructor.
4626 //! Class destructor.
4629 //! Reset and clear all internal state.
4632 //! Set the filter for a resonance at the given frequency (Hz) and radius.
4633 void setResonance(MY_FLOAT frequency
, MY_FLOAT radius
);
4635 //! Set the filter for a notch at the given frequency (Hz) and radius.
4636 void setNotch(MY_FLOAT frequency
, MY_FLOAT radius
);
4638 //! Set the filter zero coefficients for contant resonance gain.
4639 void setEqualGainZeroes();
4641 //! Initiate the envelope with a key-on event.
4644 //! Signal a key-off event to the envelope.
4647 //! Start a note with the given frequency and amplitude.
4648 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
4650 //! Stop a note with the given amplitude (speed of decay).
4651 void noteOff(MY_FLOAT amplitude
);
4653 //! Compute one output sample.
4656 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
4657 virtual void controlChange(int number
, MY_FLOAT value
);
4659 public: // SWAP formerly protected
4663 MY_FLOAT poleFrequency
;
4664 MY_FLOAT poleRadius
;
4665 MY_FLOAT zeroFrequency
;
4666 MY_FLOAT zeroRadius
;
4675 /***************************************************/
4677 \brief STK Fender Rhodes electric piano FM
4678 synthesis instrument.
4680 This class implements two simple FM Pairs
4681 summed together, also referred to as algorithm
4685 Algorithm 5 is : 4->3--\
4690 Control Change Numbers:
4691 - Modulator Index One = 2
4692 - Crossfade of Outputs = 4
4695 - ADSR 2 & 4 Target = 128
4697 The basic Chowning/Stanford FM patent expired
4698 in 1995, but there exist follow-on patents,
4699 mostly assigned to Yamaha. If you are of the
4700 type who should worry about this (making
4703 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4705 /***************************************************/
4707 #if !defined(__RHODEY_H)
4711 class Rhodey
: public FM
4714 //! Class constructor.
4717 //! Class destructor.
4720 //! Set instrument parameters for a particular frequency.
4721 void setFrequency(MY_FLOAT frequency
);
4723 //! Start a note with the given frequency and amplitude.
4724 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
4725 void noteOn(MY_FLOAT amplitude
) { noteOn(baseFrequency
* 0.5, amplitude
); }
4727 //! Compute one output sample.
4736 /***************************************************/
4738 \brief STK SKINI parsing class
4740 This class parses SKINI formatted text
4741 messages. It can be used to parse individual
4742 messages or it can be passed an entire file.
4743 The file specification is Perry's and his
4744 alone, but it's all text so it shouldn't be to
4747 SKINI (Synthesis toolKit Instrument Network
4748 Interface) is like MIDI, but allows for
4749 floating-point control changes, note numbers,
4750 etc. The following example causes a sharp
4751 middle C to be played with a velocity of 111.132:
4759 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4761 /***************************************************/
4763 #if !defined(__SKINI_H)
4768 class SKINI
: public Stk
4771 //! Default constructor used for parsing messages received externally.
4774 //! Overloaded constructor taking a SKINI formatted scorefile.
4775 SKINI(char *fileName
);
4777 //! Class destructor
4780 //! Attempt to parse the given string, returning the message type.
4782 A type value equal to zero indicates an invalid message.
4784 long parseThis(char* aString
);
4786 //! Parse the next message (if a file is loaded) and return the message type.
4788 A negative value is returned when the file end is reached.
4792 //! Return the current message type.
4793 long getType() const;
4795 //! Return the current message channel value.
4796 long getChannel() const;
4798 //! Return the current message delta time value (in seconds).
4799 MY_FLOAT
getDelta() const;
4801 //! Return the current message byte two value.
4802 MY_FLOAT
getByteTwo() const;
4804 //! Return the current message byte three value.
4805 MY_FLOAT
getByteThree() const;
4807 //! Return the current message byte two value (integer).
4808 long getByteTwoInt() const;
4810 //! Return the current message byte three value (integer).
4811 long getByteThreeInt() const;
4813 //! Return remainder string after parsing.
4814 const char* getRemainderString();
4816 //! Return the message type as a string.
4817 const char* getMessageTypeString();
4819 //! Return the SKINI type string for the given type value.
4820 const char* whatsThisType(long type
);
4822 //! Return the SKINI controller string for the given controller number.
4823 const char* whatsThisController(long number
);
4825 public: // SWAP formerly protected
4829 char msgTypeString
[64];
4836 char remainderString
[1024];
4837 char whatString
[1024];
4840 static const double Midi2Pitch
[129] = {
4841 8.18,8.66,9.18,9.72,10.30,10.91,11.56,12.25,
4842 12.98,13.75,14.57,15.43,16.35,17.32,18.35,19.45,
4843 20.60,21.83,23.12,24.50,25.96,27.50,29.14,30.87,
4844 32.70,34.65,36.71,38.89,41.20,43.65,46.25,49.00,
4845 51.91,55.00,58.27,61.74,65.41,69.30,73.42,77.78,
4846 82.41,87.31,92.50,98.00,103.83,110.00,116.54,123.47,
4847 130.81,138.59,146.83,155.56,164.81,174.61,185.00,196.00,
4848 207.65,220.00,233.08,246.94,261.63,277.18,293.66,311.13,
4849 329.63,349.23,369.99,392.00,415.30,440.00,466.16,493.88,
4850 523.25,554.37,587.33,622.25,659.26,698.46,739.99,783.99,
4851 830.61,880.00,932.33,987.77,1046.50,1108.73,1174.66,1244.51,
4852 1318.51,1396.91,1479.98,1567.98,1661.22,1760.00,1864.66,1975.53,
4853 2093.00,2217.46,2349.32,2489.02,2637.02,2793.83,2959.96,3135.96,
4854 3322.44,3520.00,3729.31,3951.07,4186.01,4434.92,4698.64,4978.03,
4855 5274.04,5587.65,5919.91,6271.93,6644.88,7040.00,7458.62,7902.13,
4856 8372.02,8869.84,9397.27,9956.06,10548.08,11175.30,11839.82,12543.85,
4866 /***************************************************/
4868 \brief STK faux conical bore reed instrument class.
4870 This class implements a "hybrid" digital
4871 waveguide instrument that can generate a
4872 variety of wind-like sounds. It has also been
4873 referred to as the "blowed string" model. The
4874 waveguide section is essentially that of a
4875 string, with one rigid and one lossy
4876 termination. The non-linear function is a
4877 reed table. The string can be "blown" at any
4878 point between the terminations, though just as
4879 with strings, it is impossible to excite the
4880 system at either end. If the excitation is
4881 placed at the string mid-point, the sound is
4882 that of a clarinet. At points closer to the
4883 "bridge", the sound is closer to that of a
4884 saxophone. See Scavone (2002) for more details.
4886 This is a digital waveguide model, making its
4887 use possibly subject to patents held by Stanford
4888 University, Yamaha, and others.
4890 Control Change Numbers:
4891 - Reed Stiffness = 2
4892 - Reed Aperture = 26
4894 - Blow Position = 11
4895 - Vibrato Frequency = 29
4897 - Breath Pressure = 128
4899 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
4901 /***************************************************/
4903 #if !defined(__SAXOFONY_H)
4904 #define __SAXOFONY_H
4907 class Saxofony
: public Instrmnt
4910 //! Class constructor, taking the lowest desired playing frequency.
4911 Saxofony(MY_FLOAT lowestFrequency
);
4913 //! Class destructor.
4916 //! Reset and clear all internal state.
4919 //! Set instrument parameters for a particular frequency.
4920 void setFrequency(MY_FLOAT frequency
);
4922 //! Set the "blowing" position between the air column terminations (0.0 - 1.0).
4923 void setBlowPosition(MY_FLOAT aPosition
);
4925 //! Apply breath pressure to instrument with given amplitude and rate of increase.
4926 void startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
);
4928 //! Decrease breath pressure with given rate of decrease.
4929 void stopBlowing(MY_FLOAT rate
);
4931 //! Start a note with the given frequency and amplitude.
4932 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
4934 //! Stop a note with the given amplitude (speed of decay).
4935 void noteOff(MY_FLOAT amplitude
);
4937 //! Compute one output sample.
4940 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
4941 void controlChange(int number
, MY_FLOAT value
);
4943 public: // SWAP formerly protected
4945 ReedTabl
*reedTable
;
4951 MY_FLOAT outputGain
;
4953 MY_FLOAT vibratoGain
;
4963 /***************************************************/
4965 \brief PhISEM and PhOLIES class.
4967 PhISEM (Physically Informed Stochastic Event
4968 Modeling) is an algorithmic approach for
4969 simulating collisions of multiple independent
4970 sound producing objects. This class is a
4971 meta-model that can simulate a Maraca, Sekere,
4972 Cabasa, Bamboo Wind Chimes, Water Drops,
4973 Tambourine, Sleighbells, and a Guiro.
4975 PhOLIES (Physically-Oriented Library of
4976 Imitated Environmental Sounds) is a similar
4977 approach for the synthesis of environmental
4978 sounds. This class implements simulations of
4979 breaking sticks, crunchy snow (or not), a
4980 wrench, sandpaper, and more.
4982 Control Change Numbers:
4985 - Number Of Objects = 11
4986 - Resonance Frequency = 1
4987 - Shake Energy = 128
4988 - Instrument Selection = 1071
5006 - Quarter + Mug = 17
5011 - Tuned Bamboo Chimes = 22
5013 by Perry R. Cook, 1996 - 1999.
5015 /***************************************************/
5017 #if !defined(__SHAKERS_H)
5022 #define NUM_INSTR 24
5024 class Shakers
: public Instrmnt
5027 //! Class constructor.
5030 //! Class destructor.
5033 //! Start a note with the given instrument and amplitude.
5035 Use the instrument numbers above, converted to frequency values
5036 as if MIDI note numbers, to select a particular instrument.
5038 virtual void ck_noteOn(MY_FLOAT amplitude
); // chuck single arg call
5039 virtual void noteOn(MY_FLOAT instrument
, MY_FLOAT amplitude
);
5041 //! Stop a note with the given amplitude (speed of decay).
5042 virtual void noteOff(MY_FLOAT amplitude
);
5044 //! Compute one output sample.
5047 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
5048 virtual void controlChange(int number
, MY_FLOAT value
);
5050 int m_noteNum
; // chuck data
5052 int setupName(char* instr
);
5053 int setupNum(int inst
);
5055 public: // SWAP formerly protected
5057 int setFreqAndReson(int which
, MY_FLOAT freq
, MY_FLOAT reson
);
5058 void setDecays(MY_FLOAT sndDecay
, MY_FLOAT sysDecay
);
5059 void setFinalZs(MY_FLOAT z0
, MY_FLOAT z1
, MY_FLOAT z2
);
5060 MY_FLOAT
wuter_tick();
5061 MY_FLOAT
tbamb_tick();
5062 MY_FLOAT
ratchet_tick();
5065 int ratchetPos
, lastRatchetPos
;
5066 MY_FLOAT shakeEnergy
;
5067 MY_FLOAT inputs
[MAX_FREQS
];
5068 MY_FLOAT outputs
[MAX_FREQS
][2];
5069 MY_FLOAT coeffs
[MAX_FREQS
][2];
5072 MY_FLOAT gains
[MAX_FREQS
];
5074 MY_FLOAT t_center_freqs
[MAX_FREQS
];
5075 MY_FLOAT center_freqs
[MAX_FREQS
];
5076 MY_FLOAT resons
[MAX_FREQS
];
5077 MY_FLOAT freq_rand
[MAX_FREQS
];
5078 int freqalloc
[MAX_FREQS
];
5079 MY_FLOAT soundDecay
;
5080 MY_FLOAT systemDecay
;
5082 MY_FLOAT collLikely
;
5083 MY_FLOAT totalEnergy
;
5084 MY_FLOAT ratchet
,ratchetDelta
;
5086 MY_FLOAT finalZCoeffs
[3];
5087 MY_FLOAT defObjs
[NUM_INSTR
];
5088 MY_FLOAT defDecays
[NUM_INSTR
];
5089 MY_FLOAT decayScale
[NUM_INSTR
];
5098 /***************************************************/
5100 \brief STK wavetable/noise instrument.
5102 This class combines a looped wave, a
5103 noise source, a biquad resonance filter,
5104 a one-pole filter, and an ADSR envelope
5105 to create some interesting sounds.
5107 Control Change Numbers:
5108 - Filter Pole Position = 2
5109 - Noise/Pitched Cross-Fade = 4
5110 - Envelope Rate = 11
5113 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5115 /***************************************************/
5117 #if !defined(__SIMPLE_H)
5121 class Simple
: public Instrmnt
5124 //! Class constructor.
5127 //! Class destructor.
5130 //! Clear internal states.
5133 //! Set instrument parameters for a particular frequency.
5134 virtual void setFrequency(MY_FLOAT frequency
);
5136 //! Start envelope toward "on" target.
5139 //! Start envelope toward "off" target.
5142 //! Start a note with the given frequency and amplitude.
5143 virtual void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
5145 //! Stop a note with the given amplitude (speed of decay).
5146 virtual void noteOff(MY_FLOAT amplitude
);
5148 //! Compute one output sample.
5149 virtual MY_FLOAT
tick();
5151 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
5152 virtual void controlChange(int number
, MY_FLOAT value
);
5154 public: // SWAP formerly protected
5160 MY_FLOAT baseFrequency
;
5170 /***************************************************/
5172 \brief STK "singing" looped soundfile class.
5174 This class contains all that is needed to make
5175 a pitched musical sound, like a simple voice
5176 or violin. In general, it will not be used
5177 alone because of munchkinification effects
5178 from pitch shifting. It will be used as an
5179 excitation source for other instruments.
5181 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5183 /***************************************************/
5185 #if !defined(__SINGWAVE_H)
5186 #define __SINGWAVE_H
5189 class SingWave
: public Stk
5192 //! Class constructor taking filename argument.
5194 An StkError will be thrown if the file is not found, its format is
5195 unknown, or a read error occurs.
5197 SingWave(const char *fileName
, bool raw
=FALSE
);
5199 //! Class destructor.
5202 //! Reset file to beginning.
5205 //! Normalize the file to a maximum of +-1.0.
5208 //! Normalize the file to a maximum of \e +- peak.
5209 void normalize(MY_FLOAT peak
);
5211 //! Set instrument parameters for a particular frequency.
5212 void setFrequency(MY_FLOAT frequency
);
5214 //! Set the vibrato frequency in Hz.
5215 void setVibratoRate(MY_FLOAT aRate
);
5217 //! Set the vibrato gain.
5218 void setVibratoGain(MY_FLOAT gain
);
5220 //! Set the random-ness amount.
5221 void setRandomGain(MY_FLOAT gain
);
5223 //! Set the sweep rate.
5224 void setSweepRate(MY_FLOAT aRate
);
5226 //! Set the gain rate.
5227 void setGainRate(MY_FLOAT aRate
);
5229 //! Set the gain target value.
5230 void setGainTarget(MY_FLOAT target
);
5238 //! Return the last output value.
5241 //! Compute one output sample.
5244 public: // SWAP formerly protected
5247 Modulate
*modulator
;
5249 Envelope
*pitchEnvelope
;
5252 MY_FLOAT lastOutput
;
5253 MY_FLOAT m_freq
; //chuck data
5262 /***************************************************/
5264 \brief STK sitar string model class.
5266 This class implements a sitar plucked string
5267 physical model based on the Karplus-Strong
5270 This is a digital waveguide model, making its
5271 use possibly subject to patents held by
5272 Stanford University, Yamaha, and others.
5273 There exist at least two patents, assigned to
5274 Stanford, bearing the names of Karplus and/or
5277 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5279 /***************************************************/
5281 #if !defined(__SITAR_H)
5285 class Sitar
: public Instrmnt
5288 //! Class constructor, taking the lowest desired playing frequency.
5289 Sitar(MY_FLOAT lowestFrequency
);
5291 //! Class destructor.
5294 //! Reset and clear all internal state.
5297 //! Set instrument parameters for a particular frequency.
5298 void setFrequency(MY_FLOAT frequency
);
5300 //! Pluck the string with the given amplitude using the current frequency.
5301 void pluck(MY_FLOAT amplitude
);
5303 //! Start a note with the given frequency and amplitude.
5304 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
5306 //! Stop a note with the given amplitude (speed of decay).
5307 void noteOff(MY_FLOAT amplitude
);
5309 //! Compute one output sample.
5312 public: // SWAP formerly protected
5314 OneZero
*loopFilter
;
5321 MY_FLOAT targetDelay
;
5331 /***************************************************/
5333 \brief STK TCP socket client/server class.
5335 This class provides a uniform cross-platform
5336 TCP socket client or socket server interface.
5337 Methods are provided for reading or writing
5338 data buffers to/from connections. This class
5339 also provides a number of static functions for
5340 use with external socket descriptors.
5342 The user is responsible for checking the values
5343 returned by the read/write methods. Values
5344 less than or equal to zero indicate a closed
5345 or lost connection or the occurence of an error.
5347 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5349 /***************************************************/
5351 #if !defined(__SOCKET_H)
5355 class Socket
: public Stk
5358 //! Default constructor which creates a local socket server on port 2006 (or the specified port number).
5360 An StkError will be thrown if a socket error occurs during instantiation.
5362 Socket( int port
= 2006 );
5364 //! Class constructor which creates a socket client connection to the specified host and port.
5366 An StkError will be thrown if a socket error occurs during instantiation.
5368 Socket( int port
, const char *hostname
);
5370 //! The class destructor closes the socket instance, breaking any existing connections.
5373 //! Connect a socket client to the specified host and port and returns the resulting socket descriptor.
5375 This method is valid for socket clients only. If it is called for
5376 a socket server, -1 is returned. If the socket client is already
5377 connected, that connection is terminated and a new connection is
5378 attempted. Server connections are made using the accept() method.
5379 An StkError will be thrown if a socket error occurs during
5380 instantiation. \sa accept
5382 int connect( int port
, const char *hostname
= "localhost" );
5384 //! Close this socket.
5387 //! Return the server/client socket descriptor.
5388 int socket( void ) const;
5390 //! Return the server/client port number.
5391 int port( void ) const;
5393 //! If this is a socket server, extract the first pending connection request from the queue and create a new connection, returning the descriptor for the accepted socket.
5395 If no connection requests are pending and the socket has not
5396 been set non-blocking, this function will block until a connection
5397 is present. If an error occurs or this is a socket client, -1 is
5402 //! If enable = false, the socket is set to non-blocking mode. When first created, sockets are by default in blocking mode.
5403 static void setBlocking( int socket
, bool enable
);
5405 //! Close the socket with the given descriptor.
5406 static void close( int socket
);
5408 //! Returns TRUE is the socket descriptor is valid.
5409 static bool isValid( int socket
);
5411 //! Write a buffer over the socket connection. Returns the number of bytes written or -1 if an error occurs.
5412 int writeBuffer(const void *buffer
, long bufferSize
, int flags
= 0);
5414 //! Write a buffer via the specified socket. Returns the number of bytes written or -1 if an error occurs.
5415 static int writeBuffer(int socket
, const void *buffer
, long bufferSize
, int flags
);
5417 //! Read a buffer from the socket connection, up to length \e bufferSize. Returns the number of bytes read or -1 if an error occurs.
5418 int readBuffer(void *buffer
, long bufferSize
, int flags
= 0);
5420 //! Read a buffer via the specified socket. Returns the number of bytes read or -1 if an error occurs.
5421 static int readBuffer(int socket
, void *buffer
, long bufferSize
, int flags
);
5423 public: // SWAP formerly protected
5432 #endif // defined(__SOCKET_H)
5437 /***************************************************/
5439 \brief STK 3D vector class.
5441 This class implements a three-dimensional vector.
5443 by Perry R. Cook, 1995 - 2002.
5445 /***************************************************/
5447 #if !defined(__VECTOR3D_H)
5448 #define __VECTOR3D_H
5453 //! Default constructor taking optional initial X, Y, and Z values.
5454 Vector3D(double initX
=0.0, double initY
=0.0, double initZ
=0.0);
5456 //! Class destructor.
5459 //! Get the current X value.
5462 //! Get the current Y value.
5465 //! Get the current Z value.
5468 //! Calculate the vector length.
5471 //! Set the X, Y, and Z values simultaniously.
5472 void setXYZ(double anX
, double aY
, double aZ
);
5474 //! Set the X value.
5475 void setX(double aval
);
5477 //! Set the Y value.
5478 void setY(double aval
);
5480 //! Set the Z value.
5481 void setZ(double aval
);
5483 public: // SWAP formerly protected
5494 /***************************************************/
5496 \brief STK sphere class.
5498 This class implements a spherical ball with
5499 radius, mass, position, and velocity parameters.
5501 by Perry R. Cook, 1995 - 2002.
5503 /***************************************************/
5505 #if !defined(__SPHERE_H)
5512 //! Constructor taking an initial radius value.
5513 Sphere(double initRadius
);
5515 //! Class destructor.
5518 //! Set the 3D center position of the sphere.
5519 void setPosition(double anX
, double aY
, double aZ
);
5521 //! Set the 3D velocity of the sphere.
5522 void setVelocity(double anX
, double aY
, double aZ
);
5524 //! Set the radius of the sphere.
5525 void setRadius(double aRadius
);
5527 //! Set the mass of the sphere.
5528 void setMass(double aMass
);
5530 //! Get the current position of the sphere as a 3D vector.
5531 Vector3D
* getPosition();
5533 //! Get the relative position of the given point to the sphere as a 3D vector.
5534 Vector3D
* getRelativePosition(Vector3D
*aPosition
);
5536 //! Set the velcoity of the sphere as a 3D vector.
5537 double getVelocity(Vector3D
* aVelocity
);
5539 //! Returns the distance from the sphere boundary to the given position (< 0 if inside).
5540 double isInside(Vector3D
*aPosition
);
5542 //! Get the current sphere radius.
5545 //! Get the current sphere mass.
5548 //! Increase the current sphere velocity by the given 3D components.
5549 void addVelocity(double anX
, double aY
, double aZ
);
5551 //! Move the sphere for the given time increment.
5552 void tick(double timeIncrement
);
5554 public: // SWAP formerly private
5555 Vector3D
*myPosition
;
5556 Vector3D
*myVelocity
;
5557 Vector3D workingVector
;
5567 /***************************************************/
5569 \brief STK plucked stiff string instrument.
5571 This class implements a simple plucked string
5572 algorithm (Karplus Strong) with enhancements
5573 (Jaffe-Smith, Smith, and others), including
5574 string stiffness and pluck position controls.
5575 The stiffness is modeled with allpass filters.
5577 This is a digital waveguide model, making its
5578 use possibly subject to patents held by
5579 Stanford University, Yamaha, and others.
5581 Control Change Numbers:
5582 - Pickup Position = 4
5583 - String Sustain = 11
5584 - String Stretch = 1
5586 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5588 /***************************************************/
5590 #if !defined(__StifKarp_h)
5591 #define __StifKarp_h
5594 class StifKarp
: public Instrmnt
5597 //! Class constructor, taking the lowest desired playing frequency.
5598 StifKarp(MY_FLOAT lowestFrequency
);
5600 //! Class destructor.
5603 //! Reset and clear all internal state.
5606 //! Set instrument parameters for a particular frequency.
5607 void setFrequency(MY_FLOAT frequency
);
5609 //! Set the stretch "factor" of the string (0.0 - 1.0).
5610 void setStretch(MY_FLOAT stretch
);
5612 //! Set the pluck or "excitation" position along the string (0.0 - 1.0).
5613 void setPickupPosition(MY_FLOAT position
);
5615 //! Set the base loop gain.
5617 The actual loop gain is set according to the frequency.
5618 Because of high-frequency loop filter roll-off, higher
5619 frequency settings have greater loop gains.
5621 void setBaseLoopGain(MY_FLOAT aGain
);
5623 //! Pluck the string with the given amplitude using the current frequency.
5624 void pluck(MY_FLOAT amplitude
);
5626 //! Start a note with the given frequency and amplitude.
5627 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
5629 //! Stop a note with the given amplitude (speed of decay).
5630 void noteOff(MY_FLOAT amplitude
);
5632 //! Compute one output sample.
5635 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
5636 void controlChange(int number
, MY_FLOAT value
);
5638 public: // SWAP formerly protected
5646 MY_FLOAT baseLoopGain
;
5647 MY_FLOAT lastFrequency
;
5648 MY_FLOAT lastLength
;
5649 MY_FLOAT stretching
;
5650 MY_FLOAT pluckAmplitude
;
5651 MY_FLOAT pickupPosition
;
5660 /***************************************************/
5662 \brief STK table lookup class.
5664 This class loads a table of floating-point
5665 doubles, which are assumed to be in big-endian
5666 format. Linear interpolation is performed for
5667 fractional lookup indexes.
5669 An StkError will be thrown if the table file
5672 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5674 /***************************************************/
5676 #if !defined(__TABLE_H)
5680 class Table
: public Stk
5683 //! Constructor loads the data from \e fileName.
5684 Table(char *fileName
);
5686 //! Class destructor.
5689 //! Return the number of elements in the table.
5690 long getLength() const;
5692 //! Return the last output value.
5693 MY_FLOAT
lastOut() const;
5695 //! Return the table value at position \e index.
5697 Linear interpolation is performed if \e index is
5700 MY_FLOAT
tick(MY_FLOAT index
);
5702 //! Take \e vectorSize index positions and return the corresponding table values in \e vector.
5703 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
5705 public: // SWAP formerly protected
5708 MY_FLOAT lastOutput
;
5712 #endif // defined(__TABLE_H)
5717 /***************************************************/
5719 \brief STK audio data output base class.
5721 This class provides output support for various
5722 audio file formats. It also serves as a base
5723 class for "realtime" streaming subclasses.
5725 WvOut writes samples to an audio file. It
5726 supports multi-channel data in interleaved
5727 format. It is important to distinguish the
5728 tick() methods, which output single samples
5729 to all channels in a sample frame, from the
5730 tickFrame() method, which takes a pointer
5731 to multi-channel sample frame data.
5733 WvOut currently supports WAV, AIFF, AIFC, SND
5734 (AU), MAT-file (Matlab), and STK RAW file
5735 formats. Signed integer (8-, 16-, and 32-bit)
5736 and floating- point (32- and 64-bit) data types
5737 are supported. STK RAW files use 16-bit
5738 integers by definition. MAT-files will always
5739 be written as 64-bit floats. If a data type
5740 specification does not match the specified file
5741 type, the data type will automatically be
5742 modified. Uncompressed data types are not
5745 Currently, WvOut is non-interpolating and the
5746 output rate is always Stk::sampleRate().
5748 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5750 /***************************************************/
5752 #if !defined(__WVOUT_H)
5757 #define BUFFER_SIZE 1024 // sample frames
5759 class WvOut
: public Stk
5763 typedef unsigned long FILE_TYPE
;
5765 static const FILE_TYPE WVOUT_RAW
; /*!< STK RAW file type. */
5766 static const FILE_TYPE WVOUT_WAV
; /*!< WAV file type. */
5767 static const FILE_TYPE WVOUT_SND
; /*!< SND (AU) file type. */
5768 static const FILE_TYPE WVOUT_AIF
; /*!< AIFF file type. */
5769 static const FILE_TYPE WVOUT_MAT
; /*!< Matlab MAT-file type. */
5771 //! Default constructor.
5774 //! Overloaded constructor used to specify a file name, type, and data format with this object.
5776 An StkError is thrown for invalid argument values or if an error occurs when initializing the output file.
5778 WvOut( const char *fileName
, unsigned int nChannels
= 1, FILE_TYPE type
= WVOUT_WAV
, Stk::STK_FORMAT format
= STK_SINT16
);
5780 //! Class destructor.
5783 //! Create a file of the specified type and name and output samples to it in the given data format.
5785 An StkError is thrown for invalid argument values or if an error occurs when initializing the output file.
5787 void openFile( const char *fileName
, unsigned int nChannels
= 1, \
5788 WvOut::FILE_TYPE type
= WVOUT_WAV
, Stk::STK_FORMAT
= STK_SINT16
);
5789 //! If a file is open, write out samples in the queue and then close it.
5790 void closeFile( void );
5792 //! Return the number of sample frames output.
5793 unsigned long getFrames( void ) const;
5795 //! Return the number of seconds of data output.
5796 MY_FLOAT
getTime( void ) const;
5798 //! Output a single sample to all channels in a sample frame.
5800 An StkError is thrown if a file write error occurs.
5802 virtual void tick(const MY_FLOAT sample
);
5804 //! Output each sample in \e vector to all channels in \e vectorSize sample frames.
5806 An StkError is thrown if a file write error occurs.
5808 virtual void tick(const MY_FLOAT
*vector
, unsigned int vectorSize
);
5810 //! Output the \e frameVector of sample frames of the given length.
5812 An StkError is thrown if a file write error occurs.
5814 virtual void tickFrame(const MY_FLOAT
*frameVector
, unsigned int frames
= 1);
5816 public: // SWAP formerly protected
5818 // Initialize class variables.
5821 // Write data to output file;
5822 virtual void writeData( unsigned long frames
);
5824 // Write STK RAW file header.
5825 bool setRawFile( const char *fileName
);
5827 // Write WAV file header.
5828 bool setWavFile( const char *fileName
);
5830 // Close WAV file, updating the header.
5831 void closeWavFile( void );
5833 // Write SND (AU) file header.
5834 bool setSndFile( const char *fileName
);
5836 // Close SND file, updating the header.
5837 void closeSndFile( void );
5839 // Write AIFF file header.
5840 bool setAifFile( const char *fileName
);
5842 // Close AIFF file, updating the header.
5843 void closeAifFile( void );
5845 // Write MAT-file header.
5846 bool setMatFile( const char *fileName
);
5848 // Close MAT-file, updating the header.
5849 void closeMatFile( void );
5855 STK_FORMAT dataType
;
5857 unsigned int channels
;
5858 unsigned long counter
;
5859 unsigned long totalCount
;
5860 char m_filename
[1024];
5862 char autoPrefix
[1024];
5866 #endif // defined(__WVOUT_H)
5871 /***************************************************/
5873 \brief STK tubular bell (orchestral chime) FM
5874 synthesis instrument.
5876 This class implements two simple FM Pairs
5877 summed together, also referred to as algorithm
5881 Algorithm 5 is : 4->3--\
5886 Control Change Numbers:
5887 - Modulator Index One = 2
5888 - Crossfade of Outputs = 4
5891 - ADSR 2 & 4 Target = 128
5893 The basic Chowning/Stanford FM patent expired
5894 in 1995, but there exist follow-on patents,
5895 mostly assigned to Yamaha. If you are of the
5896 type who should worry about this (making
5899 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5901 /***************************************************/
5903 #if !defined(__TUBEBELL_H)
5904 #define __TUBEBELL_H
5907 class TubeBell
: public FM
5910 //! Class constructor.
5913 //! Class destructor.
5916 //! Start a note with the given frequency and amplitude.
5917 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
5918 void noteOn( MY_FLOAT amplitude
) { noteOn(baseFrequency
, amplitude
); }
5920 //! Compute one output sample.
5929 /***************************************************/
5931 \brief STK two-pole filter class.
5933 This protected Filter subclass implements
5934 a two-pole digital filter. A method is
5935 provided for creating a resonance in the
5936 frequency response while maintaining a nearly
5937 constant filter gain.
5939 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
5941 /***************************************************/
5943 #if !defined(__TWOPOLE_H)
5947 class TwoPole
: public Filter
// formerly protected Filter
5951 //! Default constructor creates a second-order pass-through filter.
5954 //! Class destructor.
5957 //! Clears the internal states of the filter.
5960 //! Set the b[0] coefficient value.
5961 void setB0(MY_FLOAT b0
);
5963 //! Set the a[1] coefficient value.
5964 void setA1(MY_FLOAT a1
);
5966 //! Set the a[2] coefficient value.
5967 void setA2(MY_FLOAT a2
);
5969 //! Sets the filter coefficients for a resonance at \e frequency (in Hz).
5971 This method determines the filter coefficients corresponding to
5972 two complex-conjugate poles with the given \e frequency (in Hz)
5973 and \e radius from the z-plane origin. If \e normalize is true,
5974 the coefficients are then normalized to produce unity gain at \e
5975 frequency (the actual maximum filter gain tends to be slightly
5976 greater than unity when \e radius is not close to one). The
5977 resulting filter frequency response has a resonance at the given
5978 \e frequency. The closer the poles are to the unit-circle (\e
5979 radius close to one), the narrower the resulting resonance width.
5980 An unstable filter will result for \e radius >= 1.0. For a better
5981 resonance filter, use a BiQuad filter. \sa BiQuad filter class
5983 void setResonance(MY_FLOAT frequency
, MY_FLOAT radius
, bool normalize
= FALSE
);
5989 void ck_setResNorm( bool n
) { m_resNorm
= n
; setResonance(m_resFreq
, m_resRad
, m_resNorm
); }
5990 void ck_setResFreq( MY_FLOAT n
) { m_resFreq
= n
; setResonance(m_resFreq
, m_resRad
, m_resNorm
); }
5991 void ck_setResRad( MY_FLOAT n
) { m_resRad
= n
; setResonance(m_resFreq
, m_resRad
, m_resNorm
); }
5992 //! Set the filter gain.
5994 The gain is applied at the filter input and does not affect the
5995 coefficient values. The default gain value is 1.0.
5997 void setGain(MY_FLOAT theGain
);
5999 //! Return the current filter gain.
6000 MY_FLOAT
getGain(void) const;
6002 //! Return the last computed output value.
6003 MY_FLOAT
lastOut(void) const;
6005 //! Input one sample to the filter and return one output.
6006 MY_FLOAT
tick(MY_FLOAT sample
);
6008 //! Input \e vectorSize samples to the filter and return an equal number of outputs in \e vector.
6009 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
6017 /***************************************************/
6019 \brief Four formant synthesis instrument.
6021 This instrument contains an excitation singing
6022 wavetable (looping wave with random and
6023 periodic vibrato, smoothing on frequency,
6024 etc.), excitation noise, and four sweepable
6027 Measured formant data is included, and enough
6028 data is there to support either parallel or
6029 cascade synthesis. In the floating point case
6030 cascade synthesis is the most natural so
6031 that's what you'll find here.
6033 Control Change Numbers:
6034 - Voiced/Unvoiced Mix = 2
6035 - Vowel/Phoneme Selection = 4
6036 - Vibrato Frequency = 11
6038 - Loudness (Spectral Tilt) = 128
6040 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
6042 /***************************************************/
6043 #if !defined(__VOICFORM_H)
6044 #define __VOICFORM_H
6047 class VoicForm
: public Instrmnt
6050 //! Class constructor, taking the lowest desired playing frequency.
6053 //! Class destructor.
6056 //! Reset and clear all internal state.
6059 //! Set instrument parameters for a particular frequency.
6060 void setFrequency(MY_FLOAT frequency
);
6062 //! Set instrument parameters for the given phoneme. Returns FALSE if phoneme not found.
6063 bool setPhoneme(const char* phoneme
);
6065 //! Set the voiced component gain.
6066 void setVoiced(MY_FLOAT vGain
);
6068 //! Set the unvoiced component gain.
6069 void setUnVoiced(MY_FLOAT nGain
);
6071 //! Set the sweep rate for a particular formant filter (0-3).
6072 void setFilterSweepRate(int whichOne
, MY_FLOAT rate
);
6074 //! Set voiced component pitch sweep rate.
6075 void setPitchSweepRate(MY_FLOAT rate
);
6077 //! Start the voice.
6083 //! Start a note with the given frequency and amplitude.
6084 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
6085 //! start at current frequency..
6086 void noteOn( MY_FLOAT amplitude
);
6088 //! Stop a note with the given amplitude (speed of decay).
6089 void noteOff(MY_FLOAT amplitude
);
6091 //! Compute one output sample.
6094 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
6095 void controlChange(int number
, MY_FLOAT value
);
6097 public: // SWAP formerly protected
6102 FormSwep
*filters
[4];
6113 /***************************************************/
6115 \brief STK voice manager class.
6117 This class can be used to manage a group of
6118 STK instrument classes. Individual voices can
6119 be controlled via unique note tags.
6120 Instrument groups can be controlled by channel
6123 A previously constructed STK instrument class
6124 is linked with a voice manager using the
6125 addInstrument() function. An optional channel
6126 number argument can be specified to the
6127 addInstrument() function as well (default
6128 channel = 0). The voice manager does not
6129 delete any instrument instances ... it is the
6130 responsibility of the user to allocate and
6131 deallocate all instruments.
6133 The tick() function returns the mix of all
6134 sounding voices. Each noteOn returns a unique
6135 tag (credits to the NeXT MusicKit), so you can
6136 send control changes to specific voices within
6137 an ensemble. Alternately, control changes can
6138 be sent to all voices on a given channel.
6140 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
6142 /***************************************************/
6144 #if !defined(__VOICER_H)
6148 class Voicer
: public Stk
6151 //! Class constructor taking the maximum number of instruments to control and an optional note decay time (in seconds).
6152 Voicer( int maxInstruments
, MY_FLOAT decayTime
=0.2 );
6154 //! Class destructor.
6157 //! Add an instrument with an optional channel number to the voice manager.
6159 A set of instruments can be grouped by channel number and
6160 controlled via the functions which take a channel number argument.
6162 void addInstrument( Instrmnt
*instrument
, int channel
=0 );
6164 //! Remove the given instrument pointer from the voice manager's control.
6166 It is important that any instruments which are to be deleted by
6167 the user while the voice manager is running be first removed from
6168 the manager's control via this function!!
6170 void removeInstrument( Instrmnt
*instrument
);
6172 //! Initiate a noteOn event with the given note number and amplitude and return a unique note tag.
6174 Send the noteOn message to the first available unused voice.
6175 If all voices are sounding, the oldest voice is interrupted and
6176 sent the noteOn message. If the optional channel argument is
6177 non-zero, only voices on that channel are used. If no voices are
6178 found for a specified non-zero channel value, the function returns
6179 -1. The amplitude value should be in the range 0.0 - 128.0.
6181 long noteOn( MY_FLOAT noteNumber
, MY_FLOAT amplitude
, int channel
=0 );
6183 //! Send a noteOff to all voices having the given noteNumber and optional channel (default channel = 0).
6185 The amplitude value should be in the range 0.0 - 128.0.
6187 void noteOff( MY_FLOAT noteNumber
, MY_FLOAT amplitude
, int channel
=0 );
6189 //! Send a noteOff to the voice with the given note tag.
6191 The amplitude value should be in the range 0.0 - 128.0.
6193 void noteOff( long tag
, MY_FLOAT amplitude
);
6195 //! Send a frequency update message to all voices assigned to the optional channel argument (default channel = 0).
6197 The \e noteNumber argument corresponds to a MIDI note number, though it is a floating-point value and can range beyond the normal 0-127 range.
6199 void setFrequency( MY_FLOAT noteNumber
, int channel
=0 );
6201 //! Send a frequency update message to the voice with the given note tag.
6203 The \e noteNumber argument corresponds to a MIDI note number, though it is a floating-point value and can range beyond the normal 0-127 range.
6205 void setFrequency( long tag
, MY_FLOAT noteNumber
);
6207 //! Send a pitchBend message to all voices assigned to the optional channel argument (default channel = 0).
6208 void pitchBend( MY_FLOAT value
, int channel
=0 );
6210 //! Send a pitchBend message to the voice with the given note tag.
6211 void pitchBend( long tag
, MY_FLOAT value
);
6213 //! Send a controlChange to all instruments assigned to the optional channel argument (default channel = 0).
6214 void controlChange( int number
, MY_FLOAT value
, int channel
=0 );
6216 //! Send a controlChange to the voice with the given note tag.
6217 void controlChange( long tag
, int number
, MY_FLOAT value
);
6219 //! Send a noteOff message to all existing voices.
6220 void silence( void );
6222 //! Mix the output for all sounding voices.
6225 //! Compute \e vectorSize output mixes and return them in \e vector.
6226 MY_FLOAT
*tick(MY_FLOAT
*vector
, unsigned int vectorSize
);
6228 //! Return the last output value.
6229 MY_FLOAT
lastOut() const;
6231 //! Return the last left output value.
6232 MY_FLOAT
lastOutLeft() const;
6234 //! Return the last right output value.
6235 MY_FLOAT
lastOutRight() const;
6237 public: // SWAP formerly protected
6240 Instrmnt
*instrument
;
6242 MY_FLOAT noteNumber
;
6253 MY_FLOAT lastOutput
;
6254 MY_FLOAT lastOutputLeft
;
6255 MY_FLOAT lastOutputRight
;
6263 /***************************************************/
6265 \brief STK police/referee whistle instrument class.
6267 This class implements a hybrid physical/spectral
6268 model of a police whistle (a la Cook).
6270 Control Change Numbers:
6272 - Fipple Modulation Frequency = 11
6273 - Fipple Modulation Gain = 1
6274 - Blowing Frequency Modulation = 2
6277 by Perry R. Cook 1996 - 2002.
6279 /***************************************************/
6281 #if !defined(__WHISTLE_H)
6285 class Whistle
: public Instrmnt
6288 //! Class constructor.
6291 //! Class destructor.
6294 //! Reset and clear all internal state.
6297 //! Set instrument parameters for a particular frequency.
6298 void setFrequency(MY_FLOAT frequency
);
6300 //! Apply breath velocity to instrument with given amplitude and rate of increase.
6301 void startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
);
6303 //! Decrease breath velocity with given rate of decrease.
6304 void stopBlowing(MY_FLOAT rate
);
6306 //! Start a note with the given frequency and amplitude.
6307 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
6309 //! Stop a note with the given amplitude (speed of decay).
6310 void noteOff(MY_FLOAT amplitude
);
6312 //! Compute one output sample.
6315 //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
6316 void controlChange(int number
, MY_FLOAT value
);
6318 public: // SWAP formerly protected
6319 Vector3D
*tempVectorP
;
6320 Vector3D
*tempVector
;
6324 Sphere
*can
; // Declare a Spherical "can".
6325 Sphere
*pea
, *bumper
; // One spherical "pea", and a spherical "bumper".
6329 MY_FLOAT baseFrequency
;
6330 MY_FLOAT maxPressure
;
6332 MY_FLOAT fippleFreqMod
;
6333 MY_FLOAT fippleGainMod
;
6334 MY_FLOAT blowFreqMod
;
6337 int subSample
, subSampCount
;
6345 /***************************************************/
6347 \brief STK Wurlitzer electric piano FM
6348 synthesis instrument.
6350 This class implements two simple FM Pairs
6351 summed together, also referred to as algorithm
6355 Algorithm 5 is : 4->3--\
6360 Control Change Numbers:
6361 - Modulator Index One = 2
6362 - Crossfade of Outputs = 4
6365 - ADSR 2 & 4 Target = 128
6367 The basic Chowning/Stanford FM patent expired
6368 in 1995, but there exist follow-on patents,
6369 mostly assigned to Yamaha. If you are of the
6370 type who should worry about this (making
6373 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
6375 /***************************************************/
6377 #if !defined(__WURLEY_H)
6381 class Wurley
: public FM
6384 //! Class constructor.
6387 //! Class destructor.
6390 //! Set instrument parameters for a particular frequency.
6391 void setFrequency(MY_FLOAT frequency
);
6393 //! Start a note with the given frequency and amplitude.
6394 void noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
);
6395 void noteOn(MY_FLOAT amplitude
) { noteOn ( baseFrequency
, amplitude
); }
6397 //! Compute one output sample.
6406 /*********************************************************/
6408 Definition of SKINI Message Types and Special Symbols
6409 Synthesis toolKit Instrument Network Interface
6411 These symbols should have the form __SK_<name>_
6413 Where <name> is the string used in the SKINI stream.
6415 by Perry R. Cook, 1995 - 2002.
6417 /*********************************************************/
6419 /***** MIDI COMPATIBLE MESSAGES *****/
6420 /***** Status Bytes Have Channel=0 **/
6424 #define SK_DBL -32766
6425 #define SK_INT -32765
6426 #define SK_STR -32764
6428 #define __SK_NoteOff_ 128
6429 #define __SK_NoteOn_ 144
6430 #define __SK_PolyPressure_ 160
6431 #define __SK_ControlChange_ 176
6432 #define __SK_ProgramChange_ 192
6433 #define __SK_AfterTouch_ 208
6434 #define __SK_ChannelPressure_ __SK_AfterTouch_
6435 #define __SK_PitchWheel_ 224
6436 #define __SK_PitchBend_ __SK_PitchWheel_
6437 #define __SK_PitchChange_ 49
6439 #define __SK_Clock_ 248
6440 #define __SK_SongStart_ 250
6441 #define __SK_Continue_ 251
6442 #define __SK_SongStop_ 252
6443 #define __SK_ActiveSensing_ 254
6444 #define __SK_SystemReset_ 255
6446 #define __SK_Volume_ 7
6447 #define __SK_ModWheel_ 1
6448 #define __SK_Modulation_ __SK_ModWheel_
6449 #define __SK_Breath_ 2
6450 #define __SK_FootControl_ 4
6451 #define __SK_Portamento_ 65
6452 #define __SK_Balance_ 8
6453 #define __SK_Pan_ 10
6454 #define __SK_Sustain_ 64
6455 #define __SK_Damper_ __SK_Sustain_
6456 #define __SK_Expression_ 11
6458 #define __SK_AfterTouch_Cont_ 128
6459 #define __SK_ModFrequency_ __SK_Expression_
6461 #define __SK_ProphesyRibbon_ 16
6462 #define __SK_ProphesyWheelUp_ 2
6463 #define __SK_ProphesyWheelDown_ 3
6464 #define __SK_ProphesyPedal_ 18
6465 #define __SK_ProphesyKnob1_ 21
6466 #define __SK_ProphesyKnob2_ 22
6468 /*** Instrument Family Specific ***/
6470 #define __SK_NoiseLevel_ __SK_FootControl_
6472 #define __SK_PickPosition_ __SK_FootControl_
6473 #define __SK_StringDamping_ __SK_Expression_
6474 #define __SK_StringDetune_ __SK_ModWheel_
6475 #define __SK_BodySize_ __SK_Breath_
6476 #define __SK_BowPressure_ __SK_Breath_
6477 #define __SK_BowPosition_ __SK_PickPosition_
6478 #define __SK_BowBeta_ __SK_BowPosition_
6480 #define __SK_ReedStiffness_ __SK_Breath_
6481 #define __SK_ReedRestPos_ __SK_FootControl_
6483 #define __SK_FluteEmbouchure_ __SK_Breath_
6484 #define __SK_JetDelay_ __SK_FluteEmbouchure_
6486 #define __SK_LipTension_ __SK_Breath_
6487 #define __SK_SlideLength_ __SK_FootControl_
6489 #define __SK_StrikePosition_ __SK_PickPosition_
6490 #define __SK_StickHardness_ __SK_Breath_
6492 #define __SK_TrillDepth_ 1051
6493 #define __SK_TrillSpeed_ 1052
6494 #define __SK_StrumSpeed_ __SK_TrillSpeed_
6495 #define __SK_RollSpeed_ __SK_TrillSpeed_
6497 #define __SK_FilterQ_ __SK_Breath_
6498 #define __SK_FilterFreq_ 1062
6499 #define __SK_FilterSweepRate_ __SK_FootControl_
6501 #define __SK_ShakerInst_ 1071
6502 #define __SK_ShakerEnergy_ __SK_Breath_
6503 #define __SK_ShakerDamping_ __SK_ModFrequency_
6504 #define __SK_ShakerNumObjects_ __SK_FootControl_
6506 #define __SK_Strumming_ 1090
6507 #define __SK_NotStrumming_ 1091
6508 #define __SK_Trilling_ 1092
6509 #define __SK_NotTrilling_ 1093
6510 #define __SK_Rolling_ __SK_Strumming_
6511 #define __SK_NotRolling_ __SK_NotStrumming_
6513 #define __SK_PlayerSkill_ 2001
6514 #define __SK_Chord_ 2002
6515 #define __SK_ChordOff_ 2003
6517 #define __SK_SINGER_FilePath_ 3000
6518 #define __SK_SINGER_Frequency_ 3001
6519 #define __SK_SINGER_NoteName_ 3002
6520 #define __SK_SINGER_Shape_ 3003
6521 #define __SK_SINGER_Glot_ 3004
6522 #define __SK_SINGER_VoicedUnVoiced_ 3005
6523 #define __SK_SINGER_Synthesize_ 3006
6524 #define __SK_SINGER_Silence_ 3007
6525 #define __SK_SINGER_VibratoAmt_ __SK_ModWheel_
6526 #define __SK_SINGER_RndVibAmt_ 3008
6527 #define __SK_SINGER_VibFreq_ __SK_Expression_
6532 #define __SK_MaxMsgTypes_ 128
6534 struct SKINISpec
{ char messageString
[32];
6540 /* SEE COMMENT BLOCK AT BOTTOM FOR FIELDS AND USES */
6541 /* MessageString ,type, ch?, data2 , data3 */
6543 struct SKINISpec skini_msgs
[__SK_MaxMsgTypes_
] =
6545 {"NoteOff" , __SK_NoteOff_
, SK_DBL
, SK_DBL
},
6546 {"NoteOn" , __SK_NoteOn_
, SK_DBL
, SK_DBL
},
6547 {"PolyPressure" , __SK_PolyPressure_
, SK_DBL
, SK_DBL
},
6548 {"ControlChange" , __SK_ControlChange_
, SK_INT
, SK_DBL
},
6549 {"ProgramChange" , __SK_ProgramChange_
, SK_DBL
, SK_DBL
},
6550 {"AfterTouch" , __SK_AfterTouch_
, SK_DBL
, NOPE
},
6551 {"ChannelPressure" ,__SK_ChannelPressure_
, SK_DBL
, NOPE
},
6552 {"PitchWheel" , __SK_PitchWheel_
, SK_DBL
, NOPE
},
6553 {"PitchBend" , __SK_PitchBend_
, SK_DBL
, NOPE
},
6554 {"PitchChange" , __SK_PitchChange_
, SK_DBL
, NOPE
},
6556 {"Clock" , __SK_Clock_
, NOPE
, NOPE
},
6557 {"Undefined" , 249, NOPE
, NOPE
},
6558 {"SongStart" , __SK_SongStart_
, NOPE
, NOPE
},
6559 {"Continue" , __SK_Continue_
, NOPE
, NOPE
},
6560 {"SongStop" , __SK_SongStop_
, NOPE
, NOPE
},
6561 {"Undefined" , 253, NOPE
, NOPE
},
6562 {"ActiveSensing" , __SK_ActiveSensing_
, NOPE
, NOPE
},
6563 {"SystemReset" , __SK_SystemReset_
, NOPE
, NOPE
},
6565 {"Volume" , __SK_ControlChange_
, __SK_Volume_
, SK_DBL
},
6566 {"ModWheel" , __SK_ControlChange_
, __SK_ModWheel_
, SK_DBL
},
6567 {"Modulation" , __SK_ControlChange_
, __SK_Modulation_
, SK_DBL
},
6568 {"Breath" , __SK_ControlChange_
, __SK_Breath_
, SK_DBL
},
6569 {"FootControl" , __SK_ControlChange_
, __SK_FootControl_
, SK_DBL
},
6570 {"Portamento" , __SK_ControlChange_
, __SK_Portamento_
, SK_DBL
},
6571 {"Balance" , __SK_ControlChange_
, __SK_Balance_
, SK_DBL
},
6572 {"Pan" , __SK_ControlChange_
, __SK_Pan_
, SK_DBL
},
6573 {"Sustain" , __SK_ControlChange_
, __SK_Sustain_
, SK_DBL
},
6574 {"Damper" , __SK_ControlChange_
, __SK_Damper_
, SK_DBL
},
6575 {"Expression" , __SK_ControlChange_
, __SK_Expression_
, SK_DBL
},
6577 {"NoiseLevel" , __SK_ControlChange_
, __SK_NoiseLevel_
, SK_DBL
},
6578 {"PickPosition" , __SK_ControlChange_
, __SK_PickPosition_
, SK_DBL
},
6579 {"StringDamping" , __SK_ControlChange_
, __SK_StringDamping_
, SK_DBL
},
6580 {"StringDetune" , __SK_ControlChange_
, __SK_StringDetune_
, SK_DBL
},
6581 {"BodySize" , __SK_ControlChange_
, __SK_BodySize_
, SK_DBL
},
6582 {"BowPressure" , __SK_ControlChange_
, __SK_BowPressure_
, SK_DBL
},
6583 {"BowPosition" , __SK_ControlChange_
, __SK_BowPosition_
, SK_DBL
},
6584 {"BowBeta" , __SK_ControlChange_
, __SK_BowBeta_
, SK_DBL
},
6586 {"ReedStiffness" , __SK_ControlChange_
, __SK_ReedStiffness_
, SK_DBL
},
6587 {"ReedRestPos" , __SK_ControlChange_
, __SK_ReedRestPos_
, SK_DBL
},
6588 {"FluteEmbouchure" , __SK_ControlChange_
, __SK_FluteEmbouchure_
, SK_DBL
},
6589 {"LipTension" , __SK_ControlChange_
, __SK_LipTension_
, SK_DBL
},
6590 {"StrikePosition" , __SK_ControlChange_
, __SK_StrikePosition_
, SK_DBL
},
6591 {"StickHardness" , __SK_ControlChange_
, __SK_StickHardness_
, SK_DBL
},
6593 {"TrillDepth" , __SK_ControlChange_
, __SK_TrillDepth_
, SK_DBL
},
6594 {"TrillSpeed" , __SK_ControlChange_
, __SK_TrillSpeed_
, SK_DBL
},
6596 {"Strumming" , __SK_ControlChange_
, __SK_Strumming_
, 127 },
6597 {"NotStrumming" , __SK_ControlChange_
, __SK_Strumming_
, 0 },
6599 {"PlayerSkill" , __SK_ControlChange_
, __SK_PlayerSkill_
, SK_DBL
},
6601 {"Chord" , __SK_Chord_
, SK_DBL
, SK_STR
},
6602 {"ChordOff" , __SK_ChordOff_
, SK_DBL
, NOPE
},
6604 {"ShakerInst" , __SK_ControlChange_
, __SK_ShakerInst_
, SK_DBL
},
6605 {"Maraca" , __SK_ControlChange_
, __SK_ShakerInst_
, 0 },
6606 {"Sekere" , __SK_ControlChange_
, __SK_ShakerInst_
, 1 },
6607 {"Cabasa" , __SK_ControlChange_
, __SK_ShakerInst_
, 2 },
6608 {"Bamboo" , __SK_ControlChange_
, __SK_ShakerInst_
, 3 },
6609 {"Waterdrp" , __SK_ControlChange_
, __SK_ShakerInst_
, 4 },
6610 {"Tambourn" , __SK_ControlChange_
, __SK_ShakerInst_
, 5 },
6611 {"Sleighbl" , __SK_ControlChange_
, __SK_ShakerInst_
, 6 },
6612 {"Guiro" , __SK_ControlChange_
, __SK_ShakerInst_
, 7 },
6614 {"OpenFile" , 256, SK_STR
, NOPE
},
6615 {"SetPath" , 257, SK_STR
, NOPE
},
6617 {"FilePath" , __SK_SINGER_FilePath_
, SK_STR
, NOPE
},
6618 {"Frequency" , __SK_SINGER_Frequency_
, SK_STR
, NOPE
},
6619 {"NoteName" , __SK_SINGER_NoteName_
, SK_STR
, NOPE
},
6620 {"VocalShape" , __SK_SINGER_Shape_
, SK_STR
, NOPE
},
6621 {"Glottis" , __SK_SINGER_Glot_
, SK_STR
, NOPE
},
6622 {"VoicedUnVoiced" , __SK_SINGER_VoicedUnVoiced_
, SK_DBL
, SK_STR
},
6623 {"Synthesize" , __SK_SINGER_Synthesize_
, SK_STR
, NOPE
},
6624 {"Silence" , __SK_SINGER_Silence_
, SK_STR
, NOPE
},
6625 {"VibratoAmt" , __SK_ControlChange_
,__SK_SINGER_VibratoAmt_
,SK_DBL
},
6626 {"RndVibAmt" , __SK_SINGER_RndVibAmt_
,SK_STR
, NOPE
},
6627 {"VibFreq" , __SK_ControlChange_
,__SK_SINGER_VibFreq_
,SK_DBL
}
6631 /** FORMAT: *************************************************************/
6633 /* MessageStr$ ,type, data2, data3, */
6635 /* type is the message type sent back from the SKINI line parser. */
6636 /* data<n> is either */
6637 /* NOPE : field not used, specifically, there aren't going */
6638 /* to be any more fields on this line. So if there */
6639 /* is is NOPE in data2, data3 won't even be checked */
6640 /* SK_INT : byte (actually scanned as 32 bit signed integer) */
6641 /* If it's a MIDI data field which is required to */
6642 /* be an integer, like a controller number, it's */
6643 /* 0-127. Otherwise) get creative with SK_INTs */
6644 /* SK_DBL : double precision floating point. SKINI uses these */
6645 /* in the MIDI context for note numbers with micro */
6646 /* tuning, velocities, controller values, etc. */
6647 /* SK_STR : only valid in final field. This allows (nearly) */
6648 /* arbitrary message types to be supported by simply */
6649 /* scanning the string to EndOfLine and then passing */
6650 /* it to a more intellegent handler. For example, */
6651 /* MIDI SYSEX (system exclusive) messages of up to */
6652 /* 256bytes can be read as space-delimited integers */
6653 /* into the 1K SK_STR buffer. Longer bulk dumps, */
6654 /* soundfiles, etc. should be handled as a new */
6655 /* message type pointing to a FileName stored in the */
6656 /* SK_STR field, or as a new type of multi-line */
6659 /*************************************************************************/
6662 /***************************************************/
6664 \brief STK ADSR envelope class.
6666 This Envelope subclass implements a
6667 traditional ADSR (Attack, Decay,
6668 Sustain, Release) envelope. It
6669 responds to simple keyOn and keyOff
6670 messages, keeping track of its state.
6671 The \e state = ADSR::DONE after the
6672 envelope value reaches 0.0 in the
6673 ADSR::RELEASE state.
6675 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
6677 /***************************************************/
6679 #include "ugen_stk.h"
6681 ADSR :: ADSR() : Envelope()
6683 target
= (MY_FLOAT
) 0.0;
6684 value
= (MY_FLOAT
) 0.0;
6685 attackRate
= (MY_FLOAT
) 0.001;
6686 decayRate
= (MY_FLOAT
) 0.001;
6687 sustainLevel
= (MY_FLOAT
) 0.5;
6688 releaseRate
= (MY_FLOAT
) 0.01;
6696 void ADSR :: keyOn()
6698 target
= (MY_FLOAT
) 1.0;
6703 void ADSR :: keyOff()
6705 target
= (MY_FLOAT
) 0.0;
6710 void ADSR :: setAttackRate(MY_FLOAT aRate
)
6713 printf("[chuck](via ADSR): negative rates not allowed ... correcting!\n");
6714 attackRate
= -aRate
;
6716 else attackRate
= aRate
;
6719 void ADSR :: setDecayRate(MY_FLOAT aRate
)
6722 printf("[chuck](via ADSR): negative rates not allowed ... correcting!\n");
6725 else decayRate
= aRate
;
6728 void ADSR :: setSustainLevel(MY_FLOAT aLevel
)
6730 if (aLevel
< 0.0 ) {
6731 printf("[chuck](via ADSR): sustain level out of range ... correcting!\n");
6732 sustainLevel
= (MY_FLOAT
) 0.0;
6734 else sustainLevel
= aLevel
;
6737 void ADSR :: setReleaseRate(MY_FLOAT aRate
)
6740 printf("[chuck](via ADSR): negative rates not allowed ... correcting!\n");
6741 releaseRate
= -aRate
;
6743 else releaseRate
= aRate
;
6746 void ADSR :: setAttackTime(MY_FLOAT aTime
)
6749 printf("[chuck](via ADSR): negative rates not allowed ... correcting!\n");
6750 attackRate
= 1.0 / ( -aTime
* Stk::sampleRate() );
6752 else attackRate
= 1.0 / ( aTime
* Stk::sampleRate() );
6755 void ADSR :: setDecayTime(MY_FLOAT aTime
)
6758 printf("[chuck](via ADSR): negative times not allowed ... correcting!\n");
6759 decayRate
= 1.0 / ( -aTime
* Stk::sampleRate() );
6761 else decayRate
= 1.0 / ( aTime
* Stk::sampleRate() );
6764 void ADSR :: setReleaseTime(MY_FLOAT aTime
)
6767 printf("[chuck](via ADSR): negative times not allowed ... correcting!\n");
6768 releaseRate
= sustainLevel
/ ( -aTime
* Stk::sampleRate() );
6770 else releaseRate
= sustainLevel
/ ( aTime
* Stk::sampleRate() );
6773 void ADSR :: setAllTimes(MY_FLOAT aTime
, MY_FLOAT dTime
, MY_FLOAT sLevel
, MY_FLOAT rTime
)
6775 this->setAttackTime(aTime
);
6776 this->setDecayTime(dTime
);
6777 this->setSustainLevel(sLevel
);
6778 this->setReleaseTime(rTime
);
6781 void ADSR :: setTarget(MY_FLOAT aTarget
)
6784 if (value
< target
) {
6786 this->setSustainLevel(target
);
6789 if (value
> target
) {
6790 this->setSustainLevel(target
);
6796 void ADSR :: setValue(MY_FLOAT aValue
)
6801 this->setSustainLevel(aValue
);
6802 rate
= (MY_FLOAT
) 0.0;
6805 int ADSR :: getState(void) const
6810 MY_FLOAT
ADSR :: tick()
6816 if (value
>= target
) {
6819 target
= sustainLevel
;
6826 if (value
<= sustainLevel
) {
6827 value
= sustainLevel
;
6828 rate
= (MY_FLOAT
) 0.0;
6834 value
-= releaseRate
;
6836 value
= (MY_FLOAT
) 0.0;
6844 MY_FLOAT
*ADSR :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
6846 for (unsigned int i
=0; i
<vectorSize
; i
++)
6851 /***************************************************/
6853 \brief Banded waveguide modeling class.
6855 This class uses banded waveguide techniques to
6856 model a variety of sounds, including bowed
6857 bars, glasses, and bowls. For more
6858 information, see Essl, G. and Cook, P. "Banded
6859 Waveguides: Towards Physical Modelling of Bar
6860 Percussion Instruments", Proceedings of the
6861 1999 International Computer Music Conference.
6863 Control Change Numbers:
6866 - Strike Position = 8 (not implemented)
6867 - Vibrato Frequency = 11
6869 - Bow Velocity = 128
6871 - Instrument Presets = 16
6874 - Glass Harmonica = 2
6877 by Georg Essl, 1999 - 2002.
6878 Modified for Stk 4.0 by Gary Scavone.
6880 /***************************************************/
6884 BandedWG :: BandedWG()
6888 delay
= new DelayL
[MAX_BANDED_MODES
];
6889 bandpass
= new BiQuad
[MAX_BANDED_MODES
];
6891 bowTabl
= new BowTabl
;
6892 bowTabl
->setSlope( 3.0 );
6895 adsr
->setAllTimes( 0.02, 0.005, 0.9, 0.01);
6901 baseGain
= (MY_FLOAT
) 0.999;
6903 integrationConstant
= 0.0;
6904 trackVelocity
= false;
6912 BandedWG :: ~BandedWG()
6920 void BandedWG :: clear()
6922 for (int i
=0; i
<nModes
; i
++) {
6924 bandpass
[i
].clear();
6928 void BandedWG :: setPreset(int preset
)
6934 case 1: // Tuned Bar
6936 modes
[0] = (MY_FLOAT
) 1.0;
6937 modes
[1] = (MY_FLOAT
) 4.0198391420;
6938 modes
[2] = (MY_FLOAT
) 10.7184986595;
6939 modes
[3] = (MY_FLOAT
) 18.0697050938;
6941 for (i
=0; i
<presetModes
; i
++) {
6942 basegains
[i
] = (MY_FLOAT
) pow(0.999,(double) i
+1);
6943 excitation
[i
] = 1.0;
6948 case 2: // Glass Harmonica
6950 modes
[0] = (MY_FLOAT
) 1.0;
6951 modes
[1] = (MY_FLOAT
) 2.32;
6952 modes
[2] = (MY_FLOAT
) 4.25;
6953 modes
[3] = (MY_FLOAT
) 6.63;
6954 modes
[4] = (MY_FLOAT
) 9.38;
6955 // modes[5] = (MY_FLOAT) 12.22;
6957 for (i
=0; i
<presetModes
; i
++) {
6958 basegains
[i
] = (MY_FLOAT
) pow(0.999,(double) i
+1);
6959 excitation
[i
] = 1.0;
6962 baseGain = (MY_FLOAT) 0.99999;
6963 for (i=0; i<presetModes; i++)
6964 gains[i]= (MY_FLOAT) pow(baseGain, delay[i].getDelay()+i);
6969 case 3: // Tibetan Prayer Bowl (ICMC'02)
6971 modes
[0]=0.996108344;
6972 basegains
[0]=0.999925960128219;
6973 excitation
[0]=11.900357/10.0;
6974 modes
[1]=1.0038916562;
6975 basegains
[1]=0.999925960128219;
6976 excitation
[1]=11.900357/10.;
6978 basegains
[2]=0.999982774366897;
6979 excitation
[2]=10.914886/10.;
6980 modes
[3]=2.99329767;
6981 basegains
[3]=0.999982774366897;
6982 excitation
[3]=10.914886/10.;
6984 basegains
[4]=1.0; //0.999999999999999999987356406352;
6985 excitation
[4]=42.995041/10.;
6987 basegains
[5]=1.0; //0.999999999999999999987356406352;
6988 excitation
[5]=42.995041/10.;
6990 basegains
[6]=1.0; //0.999999999999999999996995497558225;
6991 excitation
[6]=40.063034/10.;
6992 modes
[7]=9.01549726;
6993 basegains
[7]=1.0; //0.999999999999999999996995497558225;
6994 excitation
[7]=40.063034/10.;
6996 basegains
[8]=0.999965497558225;
6997 excitation
[8]=7.063034/10.;
6999 basegains
[9]=0.999965497558225;
7000 excitation
[9]=7.063034/10.;
7001 modes
[10]=17.2808219;
7002 basegains
[10]=0.9999999999999999999965497558225;
7003 excitation
[10]=57.063034/10.;
7004 modes
[11]=21.97602739726;
7005 basegains
[11]=0.999999999999999965497558225;
7006 excitation
[11]=57.063034/10.;
7010 default: // Uniform Bar
7012 modes
[0] = (MY_FLOAT
) 1.0;
7013 modes
[1] = (MY_FLOAT
) 2.756;
7014 modes
[2] = (MY_FLOAT
) 5.404;
7015 modes
[3] = (MY_FLOAT
) 8.933;
7017 for (i
=0; i
<presetModes
; i
++) {
7018 basegains
[i
] = (MY_FLOAT
) pow(0.9,(double) i
+1);
7019 excitation
[i
] = 1.0;
7025 nModes
= presetModes
;
7026 setFrequency( freakency
);
7029 void BandedWG :: setFrequency(MY_FLOAT frequency
)
7031 freakency
= frequency
;
7032 if ( frequency
<= 0.0 ) {
7033 std::cerr
<< "[chuck](via STK): BandedWG: setFrequency parameter is less than or equal to zero!" << std::endl
;
7036 if (freakency
> 1568.0) freakency
= 1568.0;
7039 MY_FLOAT base
= Stk::sampleRate() / freakency
;
7041 for (int i
=0; i
<presetModes
; i
++) {
7042 // Calculate the delay line lengths for each mode.
7043 length
= (int)(base
/ modes
[i
]);
7044 if ( length
> 2.0) {
7045 delay
[i
].setDelay( length
);
7046 gains
[i
]=basegains
[i
];
7047 // gains[i]=(MY_FLOAT) pow(basegains[i], 1/((MY_FLOAT)delay[i].getDelay()));
7048 // std::cerr << gains[i];
7054 // std::cerr << std::endl;
7056 // Set the bandpass filter resonances
7057 radius
= 1.0 - PI
* 32 / Stk::sampleRate(); //freakency * modes[i] / Stk::sampleRate()/32;
7058 if ( radius
< 0.0 ) radius
= 0.0;
7059 bandpass
[i
].setResonance(freakency
* modes
[i
], radius
, true);
7062 bandpass
[i
].clear();
7065 //int olen = (int)(delay[0].getDelay());
7066 //strikePosition = (int)(strikePosition*(length/modes[0])/olen);
7069 void BandedWG :: setStrikePosition(MY_FLOAT position
)
7071 strikePosition
= (int)(delay
[0].getDelay() * position
/ 2.0);
7074 void BandedWG :: startBowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
7076 adsr
->setRate(rate
);
7078 maxVelocity
= 0.03 + (0.1 * amplitude
);
7081 void BandedWG :: stopBowing(MY_FLOAT rate
)
7083 adsr
->setRate(rate
);
7087 void BandedWG :: pluck(MY_FLOAT amplitude
)
7090 MY_FLOAT min_len
= delay
[nModes
-1].getDelay();
7091 for (int i
=0; i
<nModes
; i
++)
7092 for(j
=0; j
<(int)(delay
[i
].getDelay()/min_len
); j
++)
7093 delay
[i
].tick( excitation
[i
]*amplitude
/ nModes
/*/ (delay[i].getDelay()/min_len)*/);
7095 /* strikeAmp += amplitude;*/
7098 void BandedWG :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
7100 this->setFrequency(frequency
);
7103 this->pluck(amplitude
);
7105 this->startBowing(amplitude
, amplitude
* 0.001);
7107 #if defined(_STK_DEBUG_)
7108 std::cerr
<< "[chuck](via STK): BandedWG: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
7112 void BandedWG :: noteOff(MY_FLOAT amplitude
)
7115 this->stopBowing((1.0 - amplitude
) * 0.005);
7117 #if defined(_STK_DEBUG_)
7118 std::cerr
<< "[chuck](via STK): BandedWG: NoteOff amplitude = " << amplitude
<< std::endl
;
7122 MY_FLOAT
BandedWG :: tick()
7126 MY_FLOAT input
= 0.0;
7129 // input = strikeAmp/nModes;
7133 if (integrationConstant
== 0.0)
7134 velocityInput
= 0.0;
7136 velocityInput
= integrationConstant
* velocityInput
;
7138 for (k
=0; k
<nModes
; k
++)
7139 velocityInput
+= baseGain
* delay
[k
].lastOut();
7141 if ( trackVelocity
) {
7142 bowVelocity
*= 0.9995;
7143 bowVelocity
+= bowTarget
;
7147 bowVelocity
= adsr
->tick() * maxVelocity
;
7149 input
= bowVelocity
- velocityInput
;
7150 input
= input
* bowTabl
->tick(input
);
7151 input
= input
/(MY_FLOAT
)nModes
;
7154 MY_FLOAT data
= 0.0;
7155 for (k
=0; k
<nModes
; k
++) {
7156 bandpass
[k
].tick(input
+ gains
[k
] * delay
[k
].lastOut());
7157 delay
[k
].tick(bandpass
[k
].lastOut());
7158 data
+= bandpass
[k
].lastOut();
7161 //lastOutput = data * nModes;
7162 lastOutput
= data
* 4;
7166 void BandedWG :: controlChange(int number
, MY_FLOAT value
)
7168 MY_FLOAT norm
= value
* ONE_OVER_128
;
7171 std::cerr
<< "[chuck](via STK): BandedWG: Control value less than zero!" << std::endl
;
7173 else if ( norm
> 1.0 ) {
7175 std::cerr
<< "[chuck](via STK): BandedWG: Control value greater than 128.0!" << std::endl
;
7178 if (number
== __SK_BowPressure_
) { // 2
7179 m_bowpressure
= norm
;
7184 bowTabl
->setSlope( 10.0 - (9.0 * norm
));
7187 else if (number
== 4) { // 4
7188 if ( !trackVelocity
) trackVelocity
= true;
7189 bowTarget
+= 0.005 * (norm
- bowPosition
);
7191 //adsr->setTarget(bowPosition);
7193 else if (number
== 8) // 8
7194 this->setStrikePosition( norm
);
7195 else if (number
== __SK_AfterTouch_Cont_
) { // 128
7196 //bowTarget += 0.02 * (norm - bowPosition);
7197 //bowPosition = norm;
7198 if ( trackVelocity
) trackVelocity
= false;
7199 maxVelocity
= 0.13 * norm
;
7200 adsr
->setTarget(norm
);
7202 else if (number
== __SK_ModWheel_
) { // 1
7203 // baseGain = 0.9989999999 + (0.001 * norm );
7204 baseGain
= 0.8999999999999999 + (0.1 * norm
);
7205 // std::cerr << "[chuck](via STK): Yuck!" << std::endl;
7206 for (int i
=0; i
<nModes
; i
++)
7207 gains
[i
]=(MY_FLOAT
) basegains
[i
]*baseGain
;
7208 // gains[i]=(MY_FLOAT) pow(baseGain, (int)((MY_FLOAT)delay[i].getDelay()+i));
7210 else if (number
== __SK_ModFrequency_
) // 11
7211 integrationConstant
= norm
;
7212 else if (number
== __SK_Sustain_
) { // 64
7213 if (value
< 65) doPluck
= true;
7214 else doPluck
= false;
7216 else if (number
== __SK_Portamento_
) { // 65
7217 if (value
< 65) trackVelocity
= false;
7218 else trackVelocity
= true;
7220 else if (number
== __SK_ProphesyRibbon_
) // 16
7221 this->setPreset((int) value
);
7223 std::cerr
<< "[chuck](via STK): BandedWG: Undefined Control Number (" << number
<< ")!!" << std::endl
;
7225 #if defined(_STK_DEBUG_)
7226 std::cerr
<< "[chuck](via STK): BandedWG: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
7231 /***************************************************/
7233 \brief STK Hammond-oid organ FM synthesis instrument.
7235 This class implements a simple 4 operator
7236 topology, also referred to as algorithm 8 of
7248 Control Change Numbers:
7249 - Operator 4 (feedback) Gain = 2
7250 - Operator 3 Gain = 4
7253 - ADSR 2 & 4 Target = 128
7255 The basic Chowning/Stanford FM patent expired
7256 in 1995, but there exist follow-on patents,
7257 mostly assigned to Yamaha. If you are of the
7258 type who should worry about this (making
7261 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
7263 /***************************************************/
7266 BeeThree :: BeeThree()
7269 // Concatenate the STK rawwave path to the rawwave files
7270 for ( int i
=0; i
<3; i
++ )
7271 waves
[i
] = new WaveLoop( (Stk::rawwavePath() + "special:sinewave").c_str(), TRUE
);
7272 waves
[3] = new WaveLoop( "special:fwavblnk", TRUE
);
7274 this->setRatio(0, 0.999);
7275 this->setRatio(1, 1.997);
7276 this->setRatio(2, 3.006);
7277 this->setRatio(3, 6.009);
7279 gains
[0] = __FM_gains
[95];
7280 gains
[1] = __FM_gains
[95];
7281 gains
[2] = __FM_gains
[99];
7282 gains
[3] = __FM_gains
[95];
7284 adsr
[0]->setAllTimes( 0.005, 0.003, 1.0, 0.01);
7285 adsr
[1]->setAllTimes( 0.005, 0.003, 1.0, 0.01);
7286 adsr
[2]->setAllTimes( 0.005, 0.003, 1.0, 0.01);
7287 adsr
[3]->setAllTimes( 0.005, 0.001, 0.4, 0.03);
7289 twozero
->setGain( 0.1 );
7292 BeeThree :: ~BeeThree()
7296 void BeeThree :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
7298 gains
[0] = amplitude
* __FM_gains
[95];
7299 gains
[1] = amplitude
* __FM_gains
[95];
7300 gains
[2] = amplitude
* __FM_gains
[99];
7301 gains
[3] = amplitude
* __FM_gains
[95];
7302 this->setFrequency(frequency
);
7305 #if defined(_STK_DEBUG_)
7306 cerr
<< "BeeThree: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< endl
;
7310 MY_FLOAT
BeeThree :: tick()
7312 register MY_FLOAT temp
;
7314 if (modDepth
> 0.0) {
7315 temp
= 1.0 + (modDepth
* vibrato
->tick() * 0.1);
7316 waves
[0]->setFrequency(baseFrequency
* temp
* ratios
[0]);
7317 waves
[1]->setFrequency(baseFrequency
* temp
* ratios
[1]);
7318 waves
[2]->setFrequency(baseFrequency
* temp
* ratios
[2]);
7319 waves
[3]->setFrequency(baseFrequency
* temp
* ratios
[3]);
7322 waves
[3]->addPhaseOffset(twozero
->lastOut());
7323 temp
= control1
* 2.0 * gains
[3] * adsr
[3]->tick() * waves
[3]->tick();
7324 twozero
->tick(temp
);
7326 temp
+= control2
* 2.0 * gains
[2] * adsr
[2]->tick() * waves
[2]->tick();
7327 temp
+= gains
[1] * adsr
[1]->tick() * waves
[1]->tick();
7328 temp
+= gains
[0] * adsr
[0]->tick() * waves
[0]->tick();
7330 lastOutput
= temp
* 0.125;
7333 /***************************************************/
7335 \brief STK biquad (two-pole, two-zero) filter class.
7337 This protected Filter subclass implements a
7338 two-pole, two-zero digital filter. A method
7339 is provided for creating a resonance in the
7340 frequency response while maintaining a constant
7343 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
7345 /***************************************************/
7349 BiQuad :: BiQuad() : Filter()
7351 MY_FLOAT B
[3] = {1.0, 0.0, 0.0};
7352 MY_FLOAT A
[3] = {1.0, 0.0, 0.0};
7353 Filter::setCoefficients( 3, B
, 3, A
);
7360 void BiQuad :: clear(void)
7365 void BiQuad :: setB0(MY_FLOAT b0
)
7370 void BiQuad :: setB1(MY_FLOAT b1
)
7375 void BiQuad :: setB2(MY_FLOAT b2
)
7380 void BiQuad :: setA1(MY_FLOAT a1
)
7385 void BiQuad :: setA2(MY_FLOAT a2
)
7390 void BiQuad :: setResonance(MY_FLOAT frequency
, MY_FLOAT radius
, bool normalize
)
7392 a
[2] = radius
* radius
;
7393 a
[1] = -2.0 * radius
* cos(TWO_PI
* frequency
/ Stk::sampleRate());
7396 // Use zeros at +- 1 and normalize the filter peak gain.
7397 b
[0] = 0.5 - 0.5 * a
[2];
7403 void BiQuad :: setNotch(MY_FLOAT frequency
, MY_FLOAT radius
)
7405 // This method does not attempt to normalize the filter gain.
7406 b
[2] = radius
* radius
;
7407 b
[1] = (MY_FLOAT
) -2.0 * radius
* cos(TWO_PI
* (double) frequency
/ Stk::sampleRate());
7410 void BiQuad :: setEqualGainZeroes()
7417 void BiQuad :: setGain(MY_FLOAT theGain
)
7419 Filter::setGain(theGain
);
7422 MY_FLOAT
BiQuad :: getGain(void) const
7424 return Filter::getGain();
7427 MY_FLOAT
BiQuad :: lastOut(void) const
7429 return Filter::lastOut();
7432 MY_FLOAT
BiQuad :: tick(MY_FLOAT sample
)
7434 inputs
[0] = gain
* sample
;
7435 outputs
[0] = b
[0] * inputs
[0] + b
[1] * inputs
[1] + b
[2] * inputs
[2];
7436 outputs
[0] -= a
[2] * outputs
[2] + a
[1] * outputs
[1];
7437 inputs
[2] = inputs
[1];
7438 inputs
[1] = inputs
[0];
7439 outputs
[2] = outputs
[1];
7440 outputs
[1] = outputs
[0];
7445 MY_FLOAT
*BiQuad :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
7447 for (unsigned int i
=0; i
<vectorSize
; i
++)
7448 vector
[i
] = tick(vector
[i
]);
7452 /***************************************************/
7454 \brief STK blown bottle instrument class.
7456 This class implements a helmholtz resonator
7457 (biquad filter) with a polynomial jet
7458 excitation (a la Cook).
7460 Control Change Numbers:
7462 - Vibrato Frequency = 11
7466 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
7468 /***************************************************/
7471 #define __BOTTLE_RADIUS_ 0.999
7473 BlowBotl :: BlowBotl()
7477 jetTable
= new JetTabl();
7479 dcBlock
= new PoleZero();
7480 dcBlock
->setBlockZero();
7482 // Concatenate the STK rawwave path to the rawwave file
7483 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
7484 vibrato
->setFrequency( 5.925 );
7487 resonator
= new BiQuad();
7488 resonator
->setResonance(500.0, __BOTTLE_RADIUS_
, true);
7491 adsr
->setAllTimes( 0.005, 0.01, 0.8, 0.010);
7493 noise
= new Noise();
7496 maxPressure
= (MY_FLOAT
) 0.0;
7497 baseFrequency
= 0.0; // chuck data
7500 BlowBotl :: ~BlowBotl()
7510 void BlowBotl :: clear()
7515 void BlowBotl :: setFrequency(MY_FLOAT frequency
)
7517 MY_FLOAT freakency
= frequency
;
7518 if ( frequency
<= 0.0 ) {
7519 std::cerr
<< "[chuck](via STK): BlowBotl: setFrequency parameter is less than or equal to zero!" << std::endl
;
7523 resonator
->setResonance( freakency
, __BOTTLE_RADIUS_
, true );
7524 baseFrequency
= freakency
; // chuck data
7527 void BlowBotl :: startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
7529 adsr
->setAttackRate(rate
);
7530 maxPressure
= amplitude
;
7534 void BlowBotl :: stopBlowing(MY_FLOAT rate
)
7536 adsr
->setReleaseRate(rate
);
7540 void BlowBotl :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
7542 setFrequency(frequency
);
7543 startBlowing( 1.1 + (amplitude
* 0.20), amplitude
* 0.02);
7544 outputGain
= amplitude
+ 0.001;
7546 #if defined(_STK_DEBUG_)
7547 std::cerr
<< "[chuck](via STK): BlowBotl: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
7551 void BlowBotl :: noteOff(MY_FLOAT amplitude
)
7553 this->stopBlowing(amplitude
* 0.02);
7555 #if defined(_STK_DEBUG_)
7556 std::cerr
<< "[chuck](via STK): BlowBotl: NoteOff amplitude = " << amplitude
<< std::endl
;
7560 MY_FLOAT
BlowBotl :: tick()
7562 MY_FLOAT breathPressure
;
7563 MY_FLOAT randPressure
;
7564 MY_FLOAT pressureDiff
;
7566 // Calculate the breath pressure (envelope + vibrato)
7567 breathPressure
= maxPressure
* adsr
->tick();
7568 breathPressure
+= vibratoGain
* vibrato
->tick();
7570 pressureDiff
= breathPressure
- resonator
->lastOut();
7572 randPressure
= noiseGain
* noise
->tick();
7573 randPressure
*= breathPressure
;
7574 randPressure
*= (1.0 + pressureDiff
);
7576 resonator
->tick( breathPressure
+ randPressure
- ( jetTable
->tick( pressureDiff
) * pressureDiff
) );
7577 lastOutput
= 0.2 * outputGain
* dcBlock
->tick( pressureDiff
);
7582 void BlowBotl :: controlChange(int number
, MY_FLOAT value
)
7584 MY_FLOAT norm
= value
* ONE_OVER_128
;
7587 std::cerr
<< "[chuck](via STK): BlowBotl: Control value less than zero!" << std::endl
;
7589 else if ( norm
> 1.0 ) {
7591 std::cerr
<< "[chuck](via STK): BlowBotl: Control value greater than 128.0!" << std::endl
;
7594 if (number
== __SK_NoiseLevel_
) // 4
7595 noiseGain
= norm
* 30.0;
7596 else if (number
== __SK_ModFrequency_
) // 11
7597 vibrato
->setFrequency( norm
* 12.0 );
7598 else if (number
== __SK_ModWheel_
) // 1
7599 vibratoGain
= norm
* 0.4;
7600 else if (number
== __SK_AfterTouch_Cont_
) // 128
7601 adsr
->setTarget( norm
);
7603 std::cerr
<< "[chuck](via STK): BlowBotl: Undefined Control Number (" << number
<< ")!!" << std::endl
;
7605 #if defined(_STK_DEBUG_)
7606 std::cerr
<< "[chuck](via STK): BlowBotl: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
7609 /***************************************************/
7611 \brief STK clarinet physical model with one
7612 register hole and one tonehole.
7614 This class is based on the clarinet model,
7615 with the addition of a two-port register hole
7616 and a three-port dynamic tonehole
7617 implementation, as discussed by Scavone and
7620 In this implementation, the distances between
7621 the reed/register hole and tonehole/bell are
7622 fixed. As a result, both the tonehole and
7623 register hole will have variable influence on
7624 the playing frequency, which is dependent on
7625 the length of the air column. In addition,
7626 the highest playing freqeuency is limited by
7627 these fixed lengths.
7628 This is a digital waveguide model, making its
7629 use possibly subject to patents held by Stanford
7630 University, Yamaha, and others.
7632 Control Change Numbers:
7633 - Reed Stiffness = 2
7635 - Tonehole State = 11
7636 - Register State = 1
7637 - Breath Pressure = 128
7639 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
7641 /***************************************************/
7645 BlowHole :: BlowHole(MY_FLOAT lowestFrequency
)
7649 m_frequency
= 220.0;
7651 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
7652 // delays[0] is the delay line between the reed and the register vent.
7653 delays
[0] = (DelayL
*) new DelayL( 5.0 * Stk::sampleRate() / 22050.0, 100 );
7654 // delays[1] is the delay line between the register vent and the tonehole.
7655 delays
[1] = (DelayL
*) new DelayL( length
>> 1, length
);
7656 // delays[2] is the delay line between the tonehole and the end of the bore.
7657 delays
[2] = (DelayL
*) new DelayL( 4.0 * Stk::sampleRate() / 22050.0, 100 );
7658 reedTable
= new ReedTabl();
7659 reedTable
->setOffset((MY_FLOAT
) 0.7);
7660 reedTable
->setSlope((MY_FLOAT
) -0.3);
7661 filter
= new OneZero
;
7662 envelope
= new Envelope
;
7665 // Calculate the initial tonehole three-port scattering coefficient
7666 double r_b
= 0.0075; // main bore radius
7667 r_th
= 0.003; // tonehole radius
7668 scatter
= -pow(r_th
,2) / ( pow(r_th
,2) + 2*pow(r_b
,2) );
7670 // Calculate tonehole coefficients
7671 MY_FLOAT te
= 1.4 * r_th
; // effective length of the open hole
7672 th_coeff
= (te
*2*Stk::sampleRate() - 347.23) / (te
*2*Stk::sampleRate() + 347.23);
7673 tonehole
= new PoleZero
;
7674 // Start with tonehole open
7675 tonehole
->setA1(-th_coeff
);
7676 tonehole
->setB0(th_coeff
);
7677 tonehole
->setB1(-1.0);
7679 // Calculate register hole filter coefficients
7680 double r_rh
= 0.0015; // register vent radius
7681 te
= 1.4 * r_rh
; // effective length of the open hole
7682 double xi
= 0.0; // series resistance term
7683 double zeta
= 347.23 + 2*PI
*pow(r_b
,2)*xi
/1.1769;
7684 double psi
= 2*PI
*pow(r_b
,2)*te
/ (PI
*pow(r_rh
,2));
7685 rh_coeff
= (zeta
- 2 * Stk::sampleRate() * psi
) / (zeta
+ 2 * Stk::sampleRate() * psi
);
7686 rh_gain
= -347.23 / (zeta
+ 2 * Stk::sampleRate() * psi
);
7687 vent
= new PoleZero
;
7688 vent
->setA1(rh_coeff
);
7691 // Start with register vent closed
7694 // Concatenate the STK rawwave path to the rawwave file
7695 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
7696 vibrato
->setFrequency((MY_FLOAT
) 5.735);
7697 outputGain
= (MY_FLOAT
) 1.0;
7698 noiseGain
= (MY_FLOAT
) 0.2;
7699 vibratoGain
= (MY_FLOAT
) 0.01;
7702 BlowHole :: ~BlowHole()
7716 void BlowHole :: clear()
7721 filter
->tick((MY_FLOAT
) 0.0);
7722 tonehole
->tick((MY_FLOAT
) 0.0);
7723 vent
->tick((MY_FLOAT
) 0.0);
7726 void BlowHole :: setFrequency(MY_FLOAT frequency
)
7728 MY_FLOAT freakency
= frequency
;
7729 if ( frequency
<= 0.0 ) {
7730 std::cerr
<< "[chuck](via STK): BlowHole: setFrequency parameter is less than or equal to zero!" << std::endl
;
7734 // Delay = length - approximate filter delay.
7735 MY_FLOAT delay
= (Stk::sampleRate() / freakency
) * 0.5 - 3.5;
7736 delay
-= delays
[0]->getDelay() + delays
[2]->getDelay();
7738 if (delay
<= 0.0) delay
= 0.3;
7739 else if (delay
> length
) delay
= length
;
7740 delays
[1]->setDelay(delay
);
7743 void BlowHole :: setVent(MY_FLOAT newValue
)
7745 // This method allows setting of the register vent "open-ness" at
7746 // any point between "Open" (newValue = 1) and "Closed"
7750 if (newValue
<= 0.0) gain
= 0.0;
7751 else if (newValue
>= 1.0) gain
= rh_gain
;
7752 else gain
= newValue
* rh_gain
;
7754 vent
->setGain(gain
);
7757 void BlowHole :: setTonehole(MY_FLOAT newValue
)
7759 // This method allows setting of the tonehole "open-ness" at
7760 // any point between "Open" (newValue = 1) and "Closed"
7764 if (newValue
<= 0.0) new_coeff
= 0.9995;
7765 else if (newValue
>= 1.0) new_coeff
= th_coeff
;
7766 else new_coeff
= (newValue
* (th_coeff
- 0.9995)) + 0.9995;
7767 m_tonehole
= newValue
;
7768 tonehole
->setA1(-new_coeff
);
7769 tonehole
->setB0(new_coeff
);
7772 void BlowHole :: startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
7774 envelope
->setRate(rate
);
7775 envelope
->setTarget(amplitude
);
7778 void BlowHole :: stopBlowing(MY_FLOAT rate
)
7780 envelope
->setRate(rate
);
7781 envelope
->setTarget((MY_FLOAT
) 0.0);
7784 void BlowHole :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
7786 setFrequency(frequency
);
7787 startBlowing((MY_FLOAT
) 0.55 + (amplitude
* 0.30), amplitude
* 0.005);
7788 outputGain
= amplitude
+ 0.001;
7790 #if defined(_STK_DEBUG_)
7791 std::cerr
<< "[chuck](via STK): BlowHole: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
7795 void BlowHole :: noteOff(MY_FLOAT amplitude
)
7797 this->stopBlowing(amplitude
* 0.01);
7799 #if defined(_STK_DEBUG_)
7800 std::cerr
<< "[chuck](via STK): BlowHole: NoteOff amplitude = " << amplitude
<< std::endl
;
7804 MY_FLOAT
BlowHole :: tick()
7806 MY_FLOAT pressureDiff
;
7807 MY_FLOAT breathPressure
;
7810 // Calculate the breath pressure (envelope + noise + vibrato)
7811 breathPressure
= envelope
->tick();
7812 breathPressure
+= breathPressure
* noiseGain
* noise
->tick();
7813 breathPressure
+= breathPressure
* vibratoGain
* vibrato
->tick();
7815 // Calculate the differential pressure = reflected - mouthpiece pressures
7816 pressureDiff
= delays
[0]->lastOut() - breathPressure
;
7818 // Do two-port junction scattering for register vent
7819 MY_FLOAT pa
= breathPressure
+ pressureDiff
* reedTable
->tick(pressureDiff
);
7820 MY_FLOAT pb
= delays
[1]->lastOut();
7823 lastOutput
= delays
[0]->tick(vent
->lastOut()+pb
);
7824 lastOutput
*= outputGain
;
7826 // Do three-port junction scattering (under tonehole)
7827 pa
+= vent
->lastOut();
7828 pb
= delays
[2]->lastOut();
7829 MY_FLOAT pth
= tonehole
->lastOut();
7830 temp
= scatter
* (pa
+ pb
- 2 * pth
);
7832 delays
[2]->tick(filter
->tick(pa
+ temp
) * -0.95);
7833 delays
[1]->tick(pb
+ temp
);
7834 tonehole
->tick(pa
+ pb
- pth
+ temp
);
7839 void BlowHole :: controlChange(int number
, MY_FLOAT value
)
7841 MY_FLOAT norm
= value
* ONE_OVER_128
;
7844 std::cerr
<< "[chuck](via STK): BlowHole: Control value less than zero!" << std::endl
;
7846 else if ( norm
> 1.0 ) {
7848 std::cerr
<< "[chuck](via STK): BlowHole: Control value greater than 128.0!" << std::endl
;
7851 if (number
== __SK_ReedStiffness_
) { // 2
7853 reedTable
->setSlope( -0.44 + (0.26 * norm
) );
7855 else if (number
== __SK_NoiseLevel_
) // 4
7856 noiseGain
= ( norm
* 0.4);
7857 else if (number
== __SK_ModFrequency_
) // 11
7858 this->setTonehole( norm
);
7859 else if (number
== __SK_ModWheel_
) // 1
7860 this->setVent( norm
);
7861 else if (number
== __SK_AfterTouch_Cont_
) // 128
7862 envelope
->setValue( norm
);
7864 std::cerr
<< "[chuck](via STK): BlowHole: Undefined Control Number (" << number
<< ")!!" << std::endl
;
7866 #if defined(_STK_DEBUG_)
7867 std::cerr
<< "[chuck](via STK): BlowHole: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
7870 /***************************************************/
7872 \brief STK bowed string table class.
7874 This class implements a simple bowed string
7875 non-linear function, as described by Smith (1986).
7877 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
7879 /***************************************************/
7883 BowTabl :: BowTabl()
7885 offSet
= (MY_FLOAT
) 0.0;
7886 slope
= (MY_FLOAT
) 0.1;
7889 BowTabl :: ~BowTabl()
7893 void BowTabl :: setOffset(MY_FLOAT aValue
)
7898 void BowTabl :: setSlope(MY_FLOAT aValue
)
7903 MY_FLOAT
BowTabl :: lastOut() const
7908 MY_FLOAT
BowTabl :: tick(MY_FLOAT input
)
7910 // The input represents differential string vs. bow velocity.
7912 sample
= input
+ offSet
; // add bias to input
7913 sample
*= slope
; // then scale it
7914 lastOutput
= (MY_FLOAT
) fabs((double) sample
) + (MY_FLOAT
) 0.75;
7915 lastOutput
= (MY_FLOAT
) pow( lastOutput
,(MY_FLOAT
) -4.0 );
7917 // Set minimum friction to 0.0
7918 //if (lastOutput < 0.0 ) lastOutput = 0.0;
7919 // Set maximum friction to 1.0.
7920 if (lastOutput
> 1.0 ) lastOutput
= (MY_FLOAT
) 1.0;
7925 MY_FLOAT
*BowTabl :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
7927 for (unsigned int i
=0; i
<vectorSize
; i
++)
7928 vector
[i
] = tick(vector
[i
]);
7932 /***************************************************/
7934 \brief STK bowed string instrument class.
7936 This class implements a bowed string model, a
7937 la Smith (1986), after McIntyre, Schumacher,
7940 This is a digital waveguide model, making its
7941 use possibly subject to patents held by
7942 Stanford University, Yamaha, and others.
7944 Control Change Numbers:
7947 - Vibrato Frequency = 11
7951 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
7953 /***************************************************/
7956 Bowed :: Bowed(MY_FLOAT lowestFrequency
)
7959 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
7960 neckDelay
= new DelayL(100.0, length
);
7962 bridgeDelay
= new DelayL(29.0, length
);
7964 bowTable
= new BowTabl
;
7965 bowTable
->setSlope((MY_FLOAT
) 3.0);
7967 // Concatenate the STK rawwave path to the rawwave file
7968 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
7969 vibrato
->setFrequency((MY_FLOAT
) 6.12723);
7970 vibratoGain
= (MY_FLOAT
) 0.0;
7972 stringFilter
= new OnePole
;
7973 stringFilter
->setPole((MY_FLOAT
) (0.6 - (0.1 * 22050.0 / Stk::sampleRate() ) ) );
7974 stringFilter
->setGain((MY_FLOAT
) 0.95);
7976 bodyFilter
= new BiQuad
;
7977 bodyFilter
->setResonance( 500.0, 0.85, TRUE
);
7978 bodyFilter
->setGain((MY_FLOAT
) 0.2);
7981 adsr
->setAllTimes((MY_FLOAT
) 0.02,(MY_FLOAT
) 0.005,(MY_FLOAT
) 0.9,(MY_FLOAT
) 0.01);
7983 betaRatio
= (MY_FLOAT
) 0.127236;
7985 // Necessary to initialize internal variables.
7986 setFrequency( 220.0 );
7994 delete stringFilter
;
8000 void Bowed :: clear()
8003 bridgeDelay
->clear();
8006 void Bowed :: setFrequency(MY_FLOAT frequency
)
8008 MY_FLOAT freakency
= frequency
;
8009 if ( frequency
<= 0.0 ) {
8010 std::cerr
<< "[chuck](via STK): Bowed: setFrequency parameter is less than or equal to zero!" << std::endl
;
8013 m_frequency
= freakency
;
8015 // Delay = length - approximate filter delay.
8016 baseDelay
= Stk::sampleRate() / freakency
- (MY_FLOAT
) 4.0;
8017 if ( baseDelay
<= 0.0 ) baseDelay
= 0.3;
8018 bridgeDelay
->setDelay(baseDelay
* betaRatio
); // bow to bridge length
8019 neckDelay
->setDelay(baseDelay
* ((MY_FLOAT
) 1.0 - betaRatio
)); // bow to nut (finger) length
8022 void Bowed :: startBowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
8024 adsr
->setRate(rate
);
8026 maxVelocity
= (MY_FLOAT
) 0.03 + ((MY_FLOAT
) 0.2 * amplitude
);
8029 void Bowed :: stopBowing(MY_FLOAT rate
)
8031 adsr
->setRate(rate
);
8035 void Bowed :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
8037 this->startBowing(amplitude
, amplitude
* 0.001);
8038 this->setFrequency(frequency
);
8040 #if defined(_STK_DEBUG_)
8041 std::cerr
<< "[chuck](via STK): Bowed: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
8045 void Bowed :: noteOff(MY_FLOAT amplitude
)
8047 this->stopBowing(((MY_FLOAT
) 1.0 - amplitude
) * (MY_FLOAT
) 0.005);
8049 #if defined(_STK_DEBUG_)
8050 std::cerr
<< "[chuck](via STK): Bowed: NoteOff amplitude = " << amplitude
<< std::endl
;
8054 void Bowed :: setVibrato(MY_FLOAT gain
)
8059 MY_FLOAT
Bowed :: tick()
8061 MY_FLOAT bowVelocity
;
8062 MY_FLOAT bridgeRefl
;
8068 bowVelocity
= maxVelocity
* adsr
->tick();
8070 bridgeRefl
= -stringFilter
->tick( bridgeDelay
->lastOut() );
8071 nutRefl
= -neckDelay
->lastOut();
8072 stringVel
= bridgeRefl
+ nutRefl
; // Sum is String Velocity
8073 velDiff
= bowVelocity
- stringVel
; // Differential Velocity
8074 newVel
= velDiff
* bowTable
->tick( velDiff
); // Non-Linear Bow Function
8075 neckDelay
->tick(bridgeRefl
+ newVel
); // Do string propagations
8076 bridgeDelay
->tick(nutRefl
+ newVel
);
8078 if (vibratoGain
> 0.0) {
8079 neckDelay
->setDelay((baseDelay
* ((MY_FLOAT
) 1.0 - betaRatio
)) +
8080 (baseDelay
* vibratoGain
* vibrato
->tick()));
8083 lastOutput
= bodyFilter
->tick(bridgeDelay
->lastOut());
8088 void Bowed :: controlChange(int number
, MY_FLOAT value
)
8090 MY_FLOAT norm
= value
* ONE_OVER_128
;
8093 std::cerr
<< "[chuck](via STK): Bowed: Control value less than zero!" << std::endl
;
8095 else if ( norm
> 1.0 ) {
8097 std::cerr
<< "[chuck](via STK): Bowed: Control value greater than 128.0!" << std::endl
;
8100 if (number
== __SK_BowPressure_
) // 2
8101 bowTable
->setSlope( 5.0 - (4.0 * norm
) );
8102 else if (number
== __SK_BowPosition_
) { // 4
8103 betaRatio
= 0.027236 + (0.2 * norm
);
8104 bridgeDelay
->setDelay(baseDelay
* betaRatio
);
8105 neckDelay
->setDelay(baseDelay
* ((MY_FLOAT
) 1.0 - betaRatio
));
8107 else if (number
== __SK_ModFrequency_
) // 11
8108 vibrato
->setFrequency( norm
* 12.0 );
8109 else if (number
== __SK_ModWheel_
) // 1
8110 vibratoGain
= ( norm
* 0.4 );
8111 else if (number
== __SK_AfterTouch_Cont_
) // 128
8112 adsr
->setTarget(norm
);
8114 std::cerr
<< "[chuck](via STK): Bowed: Undefined Control Number (" << number
<< ")!!" << std::endl
;
8116 #if defined(_STK_DEBUG_)
8117 std::cerr
<< "[chuck](via STK): Bowed: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
8120 /***************************************************/
8122 \brief STK simple brass instrument class.
8124 This class implements a simple brass instrument
8125 waveguide model, a la Cook (TBone, HosePlayer).
8127 This is a digital waveguide model, making its
8128 use possibly subject to patents held by
8129 Stanford University, Yamaha, and others.
8131 Control Change Numbers:
8134 - Vibrato Frequency = 11
8138 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
8140 /***************************************************/
8144 Brass :: Brass(MY_FLOAT lowestFrequency
)
8146 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
8147 delayLine
= new DelayA( 0.5 * length
, length
);
8149 lipFilter
= new BiQuad();
8150 lipFilter
->setGain( 0.03 );
8151 dcBlock
= new PoleZero();
8152 dcBlock
->setBlockZero();
8155 adsr
->setAllTimes( 0.005, 0.001, 1.0, 0.010);
8157 // Concatenate the STK rawwave path to the rawwave file
8158 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
8159 vibrato
->setFrequency( 6.137 );
8163 maxPressure
= (MY_FLOAT
) 0.0;
8166 // Necessary to initialize variables.
8167 setFrequency( 220.0 );
8179 void Brass :: clear()
8186 void Brass :: setFrequency(MY_FLOAT frequency
)
8188 MY_FLOAT freakency
= frequency
;
8189 if ( frequency
<= 0.0 ) {
8190 std::cerr
<< "[chuck](via STK): Brass: setFrequency parameter is less than or equal to zero!" << std::endl
;
8194 // Fudge correction for filter delays.
8195 slideTarget
= (Stk::sampleRate() / freakency
* 2.0) + 3.0;
8196 delayLine
->setDelay(slideTarget
); // play a harmonic
8198 lipTarget
= freakency
;
8199 lipFilter
->setResonance( freakency
, 0.997 );
8202 void Brass :: setLip(MY_FLOAT frequency
)
8204 MY_FLOAT freakency
= frequency
;
8205 if ( frequency
<= 0.0 ) {
8206 std::cerr
<< "[chuck](via STK): Brass: setLip parameter is less than or equal to zero!" << std::endl
;
8210 lipFilter
->setResonance( freakency
, 0.997 );
8213 void Brass :: startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
8215 adsr
->setAttackRate(rate
);
8216 maxPressure
= amplitude
;
8220 void Brass :: stopBlowing(MY_FLOAT rate
)
8222 adsr
->setReleaseRate(rate
);
8226 void Brass :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
8228 setFrequency(frequency
);
8229 this->startBlowing(amplitude
, amplitude
* 0.001);
8231 #if defined(_STK_DEBUG_)
8232 std::cerr
<< "[chuck](via STK): Brass: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
8236 void Brass :: noteOff(MY_FLOAT amplitude
)
8238 this->stopBlowing(amplitude
* 0.005);
8240 #if defined(_STK_DEBUG_)
8241 std::cerr
<< "[chuck](via STK): Brass: NoteOff amplitude = " << amplitude
<< std::endl
;
8245 MY_FLOAT
Brass :: tick()
8247 MY_FLOAT breathPressure
= maxPressure
* adsr
->tick();
8248 breathPressure
+= vibratoGain
* vibrato
->tick();
8250 MY_FLOAT mouthPressure
= 0.3 * breathPressure
;
8251 MY_FLOAT borePressure
= 0.85 * delayLine
->lastOut();
8252 MY_FLOAT deltaPressure
= mouthPressure
- borePressure
; // Differential pressure.
8253 deltaPressure
= lipFilter
->tick( deltaPressure
); // Force - > position.
8254 deltaPressure
*= deltaPressure
; // Basic position to area mapping.
8255 if ( deltaPressure
> 1.0 ) deltaPressure
= 1.0; // Non-linear saturation.
8256 // The following input scattering assumes the mouthPressure = area.
8257 lastOutput
= deltaPressure
* mouthPressure
+ ( 1.0 - deltaPressure
) * borePressure
;
8258 lastOutput
= delayLine
->tick( dcBlock
->tick( lastOutput
) );
8263 void Brass :: controlChange(int number
, MY_FLOAT value
)
8265 MY_FLOAT norm
= value
* ONE_OVER_128
;
8268 std::cerr
<< "[chuck](via STK): Brass: Control value less than zero!" << std::endl
;
8270 else if ( norm
> 1.0 ) {
8272 std::cerr
<< "[chuck](via STK): Brass: Control value greater than 128.0!" << std::endl
;
8275 if (number
== __SK_LipTension_
) { // 2
8276 MY_FLOAT temp
= lipTarget
* pow( 4.0, (2.0 * norm
) - 1.0 );
8279 else if (number
== __SK_SlideLength_
) // 4
8280 delayLine
->setDelay( slideTarget
* (0.5 + norm
) );
8281 else if (number
== __SK_ModFrequency_
) // 11
8282 vibrato
->setFrequency( norm
* 12.0 );
8283 else if (number
== __SK_ModWheel_
) // 1
8284 vibratoGain
= norm
* 0.4;
8285 else if (number
== __SK_AfterTouch_Cont_
) // 128
8286 adsr
->setTarget( norm
);
8288 std::cerr
<< "[chuck](via STK): Brass: Undefined Control Number (" << number
<< ")!!" << std::endl
;
8290 #if defined(_STK_DEBUG_)
8291 std::cerr
<< "[chuck](via STK): Brass: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
8294 /***************************************************/
8296 \brief STK chorus effect class.
8298 This class implements a chorus effect.
8300 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
8302 /***************************************************/
8306 Chorus :: Chorus(MY_FLOAT baseDelay
)
8308 delayLine
[0] = new DelayL((long) baseDelay
, (long) (baseDelay
* 1.414) + 2);
8309 delayLine
[1] = new DelayL((long) (baseDelay
), (long) baseDelay
+ 2);
8310 baseLength
= baseDelay
;
8312 // Concatenate the STK rawwave path to the rawwave file
8313 mods
[0] = new WaveLoop( "special:sinewave", TRUE
);
8314 mods
[1] = new WaveLoop( "special:sinewave", TRUE
);
8315 mods
[0]->setFrequency(0.2);
8316 mods
[1]->setFrequency(0.222222);
8324 delete delayLine
[0];
8325 delete delayLine
[1];
8330 void Chorus :: clear()
8332 delayLine
[0]->clear();
8333 delayLine
[1]->clear();
8334 lastOutput
[0] = 0.0;
8335 lastOutput
[1] = 0.0;
8338 void Chorus :: setEffectMix(MY_FLOAT mix
)
8342 std::cerr
<< "[chuck](via STK): Chorus: setEffectMix parameter is less than zero!" << std::endl
;
8345 else if ( mix
> 1.0 ) {
8346 std::cerr
<< "[chuck](via STK): Chorus: setEffectMix parameter is greater than 1.0!" << std::endl
;
8351 void Chorus :: setModDepth(MY_FLOAT depth
)
8356 void Chorus :: setModFrequency(MY_FLOAT frequency
)
8358 mods
[0]->setFrequency(frequency
);
8359 mods
[1]->setFrequency(frequency
* 1.1111);
8362 MY_FLOAT
Chorus :: lastOut() const
8364 return (lastOutput
[0] + lastOutput
[1]) * (MY_FLOAT
) 0.5;
8367 MY_FLOAT
Chorus :: lastOutLeft() const
8369 return lastOutput
[0];
8372 MY_FLOAT
Chorus :: lastOutRight() const
8374 return lastOutput
[1];
8377 MY_FLOAT
Chorus :: tick(MY_FLOAT input
)
8379 delayLine
[0]->setDelay(baseLength
* 0.707 * (1.0 + mods
[0]->tick()));
8380 delayLine
[1]->setDelay(baseLength
* 0.5 * (1.0 - mods
[1]->tick()));
8381 lastOutput
[0] = input
* (1.0 - effectMix
);
8382 lastOutput
[0] += effectMix
* delayLine
[0]->tick(input
);
8383 lastOutput
[1] = input
* (1.0 - effectMix
);
8384 lastOutput
[1] += effectMix
* delayLine
[1]->tick(input
);
8385 return (lastOutput
[0] + lastOutput
[1]) * (MY_FLOAT
) 0.5;
8388 MY_FLOAT
*Chorus :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
8390 for (unsigned int i
=0; i
<vectorSize
; i
++)
8391 vector
[i
] = tick(vector
[i
]);
8395 /***************************************************/
8397 \brief STK clarinet physical model class.
8399 This class implements a simple clarinet
8400 physical model, as discussed by Smith (1986),
8401 McIntyre, Schumacher, Woodhouse (1983), and
8404 This is a digital waveguide model, making its
8405 use possibly subject to patents held by Stanford
8406 University, Yamaha, and others.
8408 Control Change Numbers:
8409 - Reed Stiffness = 2
8411 - Vibrato Frequency = 11
8413 - Breath Pressure = 128
8415 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
8417 /***************************************************/
8420 Clarinet :: Clarinet(MY_FLOAT lowestFrequency
)
8422 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
8423 delayLine
= new DelayL( (MY_FLOAT
)(length
/ 2.0), length
);
8424 reedTable
= new ReedTabl();
8425 reedTable
->setOffset((MY_FLOAT
) 0.7);
8426 reedTable
->setSlope((MY_FLOAT
) -0.3);
8427 filter
= new OneZero
;
8428 envelope
= new Envelope
;
8431 // Concatenate the STK rawwave path to the rawwave file
8432 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
8433 vibrato
->setFrequency((MY_FLOAT
) 5.735);
8434 outputGain
= (MY_FLOAT
) 1.0;
8435 noiseGain
= (MY_FLOAT
) 0.2;
8436 vibratoGain
= (MY_FLOAT
) 0.1;
8439 Clarinet :: ~Clarinet()
8449 void Clarinet :: clear()
8452 filter
->tick((MY_FLOAT
) 0.0);
8455 void Clarinet :: setFrequency(MY_FLOAT frequency
)
8457 MY_FLOAT freakency
= frequency
;
8458 if ( frequency
<= 0.0 ) {
8459 std::cerr
<< "[chuck](via STK): Clarinet: setFrequency parameter is less than or equal to zero!" << std::endl
;
8463 // Delay = length - approximate filter delay.
8464 MY_FLOAT delay
= (Stk::sampleRate() / freakency
) * 0.5 - 1.5;
8465 if (delay
<= 0.0) delay
= 0.3;
8466 else if (delay
> length
) delay
= length
;
8467 delayLine
->setDelay(delay
);
8470 void Clarinet :: startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
8472 envelope
->setRate(rate
);
8473 envelope
->setTarget(amplitude
);
8476 void Clarinet :: stopBlowing(MY_FLOAT rate
)
8478 envelope
->setRate(rate
);
8479 envelope
->setTarget((MY_FLOAT
) 0.0);
8482 void Clarinet :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
8484 this->setFrequency(frequency
);
8485 this->startBlowing((MY_FLOAT
) 0.55 + (amplitude
* (MY_FLOAT
) 0.30), amplitude
* (MY_FLOAT
) 0.005);
8486 outputGain
= amplitude
+ (MY_FLOAT
) 0.001;
8488 #if defined(_STK_DEBUG_)
8489 std::cerr
<< "[chuck](via STK): Clarinet: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
8493 void Clarinet :: noteOff(MY_FLOAT amplitude
)
8495 this->stopBlowing(amplitude
* (MY_FLOAT
) 0.01);
8497 #if defined(_STK_DEBUG_)
8498 std::cerr
<< "[chuck](via STK): Clarinet: NoteOff amplitude = " << amplitude
<< std::endl
;
8502 MY_FLOAT
Clarinet :: tick()
8504 MY_FLOAT pressureDiff
;
8505 MY_FLOAT breathPressure
;
8507 // Calculate the breath pressure (envelope + noise + vibrato)
8508 breathPressure
= envelope
->tick();
8509 breathPressure
+= breathPressure
* noiseGain
* noise
->tick();
8510 breathPressure
+= breathPressure
* vibratoGain
* vibrato
->tick();
8512 // Perform commuted loss filtering.
8513 pressureDiff
= -0.95 * filter
->tick(delayLine
->lastOut());
8515 // Calculate pressure difference of reflected and mouthpiece pressures.
8516 pressureDiff
= pressureDiff
- breathPressure
;
8518 // Perform non-linear scattering using pressure difference in reed function.
8519 lastOutput
= delayLine
->tick(breathPressure
+ pressureDiff
* reedTable
->tick(pressureDiff
));
8521 // Apply output gain.
8522 lastOutput
*= outputGain
;
8527 void Clarinet :: controlChange(int number
, MY_FLOAT value
)
8529 MY_FLOAT norm
= value
* ONE_OVER_128
;
8532 std::cerr
<< "[chuck](via STK): Clarinet: Control value less than zero!" << std::endl
;
8534 else if ( norm
> 1.0 ) {
8536 std::cerr
<< "[chuck](via STK): Clarinet: Control value greater than 128.0!" << std::endl
;
8539 if (number
== __SK_ReedStiffness_
) // 2
8540 reedTable
->setSlope((MY_FLOAT
) -0.44 + ( (MY_FLOAT
) 0.26 * norm
));
8541 else if (number
== __SK_NoiseLevel_
) // 4
8542 noiseGain
= (norm
* (MY_FLOAT
) 0.4);
8543 else if (number
== __SK_ModFrequency_
) // 11
8544 vibrato
->setFrequency((norm
* (MY_FLOAT
) 12.0));
8545 else if (number
== __SK_ModWheel_
) // 1
8546 vibratoGain
= (norm
* (MY_FLOAT
) 0.5);
8547 else if (number
== __SK_AfterTouch_Cont_
) // 128
8548 envelope
->setValue(norm
);
8550 std::cerr
<< "[chuck](via STK): Clarinet: Undefined Control Number (" << number
<< ")!!" << std::endl
;
8552 #if defined(_STK_DEBUG_)
8553 std::cerr
<< "[chuck](via STK): Clarinet: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
8556 /***************************************************/
8558 \brief STK non-interpolating delay line class.
8560 This protected Filter subclass implements
8561 a non-interpolating digital delay-line.
8562 A fixed maximum length of 4095 and a delay
8563 of zero is set using the default constructor.
8564 Alternatively, the delay and maximum length
8565 can be set during instantiation with an
8566 overloaded constructor.
8568 A non-interpolating delay line is typically
8569 used in fixed delay-length applications, such
8570 as for reverberation.
8572 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
8574 /***************************************************/
8580 this->set( 0, 4096 );
8583 Delay :: Delay(long theDelay
, long maxDelay
)
8585 this->set( theDelay
, maxDelay
);
8588 void Delay :: set( long delay
, long max
)
8590 // Writing before reading allows delays from 0 to length-1.
8591 // If we want to allow a delay of maxDelay, we need a
8592 // delay-line of length = maxDelay+1.
8595 // We need to delete the previously allocated inputs.
8596 if( inputs
) delete [] inputs
;
8597 inputs
= new MY_FLOAT
[length
];
8601 this->setDelay(delay
);
8608 void Delay :: clear(void)
8611 for (i
=0;i
<length
;i
++) inputs
[i
] = 0.0;
8615 void Delay :: setDelay(long theDelay
)
8617 if (theDelay
> length
-1) { // The value is too big.
8618 std::cerr
<< "[chuck](via STK): Delay: setDelay(" << theDelay
<< ") too big!" << std::endl
;
8619 // Force delay to maxLength.
8620 outPoint
= inPoint
+ 1;
8623 else if (theDelay
< 0 ) {
8624 std::cerr
<< "[chuck](via STK): Delay: setDelay(" << theDelay
<< ") less than zero!" << std::endl
;
8629 outPoint
= inPoint
- (long) theDelay
; // read chases write
8633 while (outPoint
< 0) outPoint
+= length
; // modulo maximum length
8636 MY_FLOAT
Delay :: getDelay(void) const
8641 MY_FLOAT
Delay :: energy(void) const
8644 register MY_FLOAT e
= 0;
8645 if (inPoint
>= outPoint
) {
8646 for (i
=outPoint
; i
<inPoint
; i
++) {
8647 register MY_FLOAT t
= inputs
[i
];
8651 for (i
=outPoint
; i
<length
; i
++) {
8652 register MY_FLOAT t
= inputs
[i
];
8655 for (i
=0; i
<inPoint
; i
++) {
8656 register MY_FLOAT t
= inputs
[i
];
8663 MY_FLOAT
Delay :: contentsAt(unsigned long tapDelay
) const
8667 std::cerr
<< "[chuck](via STK): Delay: contentsAt(" << tapDelay
<< ") too small!" << std::endl
;
8670 else if (i
> delay
) {
8671 std::cerr
<< "[chuck](via STK): Delay: contentsAt(" << tapDelay
<< ") too big!" << std::endl
;
8675 long tap
= inPoint
- i
;
8676 if (tap
< 0) // Check for wraparound.
8682 MY_FLOAT
Delay :: lastOut(void) const
8684 return Filter::lastOut();
8687 MY_FLOAT
Delay :: nextOut(void) const
8689 return inputs
[outPoint
];
8692 MY_FLOAT
Delay :: tick(MY_FLOAT sample
)
8694 inputs
[inPoint
++] = sample
;
8696 // Check for end condition
8697 if (inPoint
== length
)
8700 // Read out next value
8701 outputs
[0] = inputs
[outPoint
++];
8703 if (outPoint
>=length
)
8709 MY_FLOAT
*Delay :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
8711 for (unsigned int i
=0; i
<vectorSize
; i
++)
8712 vector
[i
] = tick(vector
[i
]);
8716 /***************************************************/
8718 \brief STK allpass interpolating delay line class.
8720 This Delay subclass implements a fractional-
8721 length digital delay-line using a first-order
8722 allpass filter. A fixed maximum length
8723 of 4095 and a delay of 0.5 is set using the
8724 default constructor. Alternatively, the
8725 delay and maximum length can be set during
8726 instantiation with an overloaded constructor.
8728 An allpass filter has unity magnitude gain but
8729 variable phase delay properties, making it useful
8730 in achieving fractional delays without affecting
8731 a signal's frequency magnitude response. In
8732 order to achieve a maximally flat phase delay
8733 response, the minimum delay possible in this
8734 implementation is limited to a value of 0.5.
8736 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
8738 /***************************************************/
8744 this->setDelay( 0.5 );
8749 DelayA :: DelayA(MY_FLOAT theDelay
, long maxDelay
)
8751 // Writing before reading allows delays from 0 to length-1.
8752 length
= maxDelay
+1;
8754 if ( length
> 4096 ) {
8755 // We need to delete the previously allocated inputs.
8757 inputs
= new MY_FLOAT
[length
];
8762 this->setDelay(theDelay
);
8767 void DelayA :: set( MY_FLOAT delay
, long max
)
8769 // Writing before reading allows delays from 0 to length-1.
8770 // If we want to allow a delay of maxDelay, we need a
8771 // delay-line of length = maxDelay+1.
8774 // We need to delete the previously allocated inputs.
8775 if( inputs
) delete [] inputs
;
8776 inputs
= new MY_FLOAT
[length
];
8780 this->setDelay(delay
);
8789 void DelayA :: clear()
8795 void DelayA :: setDelay(MY_FLOAT theDelay
)
8797 MY_FLOAT outPointer
;
8799 if (theDelay
> length
-1) {
8800 std::cerr
<< "[chuck](via STK): DelayA: setDelay(" << theDelay
<< ") too big!" << std::endl
;
8801 // Force delay to maxLength
8802 outPointer
= inPoint
+ 1.0;
8805 else if (theDelay
< 0.5) {
8806 std::cerr
<< "[chuck](via STK): DelayA: setDelay(" << theDelay
<< ") less than 0.5 not possible!" << std::endl
;
8807 outPointer
= inPoint
+ 0.4999999999;
8811 outPointer
= inPoint
- theDelay
+ 1.0; // outPoint chases inpoint
8816 outPointer
+= length
; // modulo maximum length
8818 outPoint
= (long) outPointer
; // integer part
8819 alpha
= 1.0 + outPoint
- outPointer
; // fractional part
8822 // The optimal range for alpha is about 0.5 - 1.5 in order to
8823 // achieve the flattest phase delay response.
8825 if (outPoint
>= length
) outPoint
-= length
;
8826 alpha
+= (MY_FLOAT
) 1.0;
8829 coeff
= ((MY_FLOAT
) 1.0 - alpha
) /
8830 ((MY_FLOAT
) 1.0 + alpha
); // coefficient for all pass
8833 MY_FLOAT
DelayA :: nextOut(void)
8836 // Do allpass interpolation delay.
8837 nextOutput
= -coeff
* outputs
[0];
8838 nextOutput
+= apInput
+ (coeff
* inputs
[outPoint
]);
8845 MY_FLOAT
DelayA :: tick(MY_FLOAT sample
)
8847 inputs
[inPoint
++] = sample
;
8849 // Increment input pointer modulo length.
8850 if (inPoint
== length
)
8853 outputs
[0] = nextOut();
8856 // Save the allpass input and increment modulo length.
8857 apInput
= inputs
[outPoint
++];
8858 if (outPoint
== length
)
8863 /***************************************************/
8865 \brief STK linear interpolating delay line class.
8867 This Delay subclass implements a fractional-
8868 length digital delay-line using first-order
8869 linear interpolation. A fixed maximum length
8870 of 4095 and a delay of zero is set using the
8871 default constructor. Alternatively, the
8872 delay and maximum length can be set during
8873 instantiation with an overloaded constructor.
8875 Linear interpolation is an efficient technique
8876 for achieving fractional delay lengths, though
8877 it does introduce high-frequency signal
8878 attenuation to varying degrees depending on the
8879 fractional delay setting. The use of higher
8880 order Lagrange interpolators can typically
8881 improve (minimize) this attenuation characteristic.
8883 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
8885 /***************************************************/
8894 DelayL :: DelayL(MY_FLOAT theDelay
, long maxDelay
)
8896 // Writing before reading allows delays from 0 to length-1.
8897 length
= maxDelay
+1;
8899 if ( length
> 4096 ) {
8900 // We need to delete the previously allocated inputs.
8902 inputs
= new MY_FLOAT
[length
];
8907 this->setDelay(theDelay
);
8915 void DelayL :: set( MY_FLOAT delay
, long max
)
8917 // Writing before reading allows delays from 0 to length-1.
8918 // If we want to allow a delay of maxDelay, we need a
8919 // delay-line of length = maxDelay+1.
8922 // We need to delete the previously allocated inputs.
8923 if( inputs
) delete [] inputs
;
8924 inputs
= new MY_FLOAT
[length
];
8928 this->setDelay(delay
);
8932 void DelayL :: setDelay(MY_FLOAT theDelay
)
8934 MY_FLOAT outPointer
;
8936 if (theDelay
> length
-1) {
8937 std::cerr
<< "[chuck](via STK): DelayL: setDelay(" << theDelay
<< ") too big!" << std::endl
;
8938 // Force delay to maxLength
8939 outPointer
= inPoint
+ 1.0;
8942 else if (theDelay
< 0 ) {
8943 std::cerr
<< "[chuck](via STK): DelayL: setDelay(" << theDelay
<< ") less than zero!" << std::endl
;
8944 outPointer
= inPoint
;
8948 outPointer
= inPoint
- theDelay
; // read chases write
8952 while (outPointer
< 0)
8953 outPointer
+= length
; // modulo maximum length
8955 outPoint
= (long) outPointer
; // integer part
8956 alpha
= outPointer
- outPoint
; // fractional part
8957 omAlpha
= (MY_FLOAT
) 1.0 - alpha
;
8960 MY_FLOAT
DelayL :: nextOut(void)
8963 // First 1/2 of interpolation
8964 nextOutput
= inputs
[outPoint
] * omAlpha
;
8965 // Second 1/2 of interpolation
8966 if (outPoint
+1 < length
)
8967 nextOutput
+= inputs
[outPoint
+1] * alpha
;
8969 nextOutput
+= inputs
[0] * alpha
;
8976 MY_FLOAT
DelayL :: tick(MY_FLOAT sample
)
8978 inputs
[inPoint
++] = sample
;
8980 // Increment input pointer modulo length.
8981 if (inPoint
== length
)
8984 outputs
[0] = nextOut();
8987 // Increment output pointer modulo length.
8988 if (++outPoint
>= length
)
8993 /***************************************************/
8995 \brief STK drum sample player class.
8997 This class implements a drum sampling
8998 synthesizer using WvIn objects and one-pole
8999 filters. The drum rawwave files are sampled
9000 at 22050 Hz, but will be appropriately
9001 interpolated for other sample rates. You can
9002 specify the maximum polyphony (maximum number
9003 of simultaneous voices) via a #define in the
9006 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
9008 /***************************************************/
9012 // Not really General MIDI yet. Coming soon.
9013 unsigned char genMIDIMap
[128] =
9014 { 0,0,0,0,0,0,0,0, // 0-7
9015 0,0,0,0,0,0,0,0, // 8-15
9016 0,0,0,0,0,0,0,0, // 16-23
9017 0,0,0,0,0,0,0,0, // 24-31
9018 0,0,0,0,1,0,2,0, // 32-39
9019 2,3,6,3,6,4,7,4, // 40-47
9020 5,8,5,0,0,0,10,0, // 48-55
9021 9,0,0,0,0,0,0,0, // 56-63
9022 0,0,0,0,0,0,0,0, // 64-71
9023 0,0,0,0,0,0,0,0, // 72-79
9024 0,0,0,0,0,0,0,0, // 80-87
9025 0,0,0,0,0,0,0,0, // 88-95
9026 0,0,0,0,0,0,0,0, // 96-103
9027 0,0,0,0,0,0,0,0, // 104-111
9028 0,0,0,0,0,0,0,0, // 112-119
9029 0,0,0,0,0,0,0,0 // 120-127
9032 //XXX changed this from 16 to 32 for the 'special' convention..also, we do not have these linked
9034 char waveNames
[DRUM_NUMWAVES
][32] =
9049 Drummer :: Drummer() : Instrmnt()
9051 for (int i
=0; i
<DRUM_POLYPHONY
; i
++) {
9052 filters
[i
] = new OnePole
;
9056 // This counts the number of sounding voices.
9060 Drummer :: ~Drummer()
9063 for ( i
=0; i
<nSounding
-1; i
++ ) delete waves
[i
];
9064 for ( i
=0; i
<DRUM_POLYPHONY
; i
++ ) delete filters
[i
];
9067 void Drummer :: noteOn(MY_FLOAT instrument
, MY_FLOAT amplitude
)
9069 #if defined(_STK_DEBUG_)
9070 std::cerr
<< "[chuck](via STK): Drummer: NoteOn instrument = " << instrument
<< ", amplitude = " << amplitude
<< std::endl
;
9073 MY_FLOAT gain
= amplitude
;
9074 if ( amplitude
> 1.0 ) {
9075 std::cerr
<< "[chuck](via STK): Drummer: noteOn amplitude parameter is greater than 1.0!" << std::endl
;
9078 else if ( amplitude
< 0.0 ) {
9079 std::cerr
<< "[chuck](via STK): Drummer: noteOn amplitude parameter is less than 0.0!" << std::endl
;
9083 // Yes, this is tres kludgey.
9084 int noteNum
= (int) ((12*log(instrument
/220.0)/log(2.0)) + 57.01);
9086 // Check first to see if there's already one like this sounding.
9087 int i
, waveIndex
= -1;
9088 for (i
=0; i
<DRUM_POLYPHONY
; i
++) {
9089 if (sounding
[i
] == noteNum
) waveIndex
= i
;
9092 if ( waveIndex
>= 0 ) {
9093 // Reset this sound.
9094 waves
[waveIndex
]->reset();
9095 filters
[waveIndex
]->setPole((MY_FLOAT
) 0.999 - (gain
* 0.6));
9096 filters
[waveIndex
]->setGain(gain
);
9099 if (nSounding
== DRUM_POLYPHONY
) {
9100 // If we're already at maximum polyphony, then preempt the oldest voice.
9102 filters
[0]->clear();
9103 WvIn
*tempWv
= waves
[0];
9104 OnePole
*tempFilt
= filters
[0];
9105 // Re-order the list.
9106 for (i
=0; i
<DRUM_POLYPHONY
-1; i
++) {
9107 waves
[i
] = waves
[i
+1];
9108 filters
[i
] = filters
[i
+1];
9110 waves
[DRUM_POLYPHONY
-1] = tempWv
;
9111 filters
[DRUM_POLYPHONY
-1] = tempFilt
;
9116 sounding
[nSounding
-1] = noteNum
;
9117 // Concatenate the STK rawwave path to the rawwave file
9118 waves
[nSounding
-1] = new WvIn( (Stk::rawwavePath() + waveNames
[genMIDIMap
[noteNum
]]).c_str(), TRUE
);
9119 if (Stk::sampleRate() != 22050.0)
9120 waves
[nSounding
-1]->setRate( 22050.0 / Stk::sampleRate() );
9121 filters
[nSounding
-1]->setPole((MY_FLOAT
) 0.999 - (gain
* 0.6) );
9122 filters
[nSounding
-1]->setGain( gain
);
9125 #if defined(_STK_DEBUG_)
9126 std::cerr
<< "[chuck](via STK): Number Sounding = " << nSounding
<< std::endl
;
9127 for (i
=0; i
<nSounding
; i
++) std::cerr
<< sounding
[i
] << " ";
9128 std::cerr
<< "[chuck](via STK): \n";
9132 void Drummer :: noteOff(MY_FLOAT amplitude
)
9134 // Set all sounding wave filter gains low.
9136 while(i
< nSounding
) {
9137 filters
[i
++]->setGain( amplitude
* 0.01 );
9141 MY_FLOAT
Drummer :: tick()
9143 MY_FLOAT output
= 0.0;
9147 while (i
< nSounding
) {
9148 if ( waves
[i
]->isFinished() ) {
9150 tempFilt
= filters
[i
];
9151 // Re-order the list.
9152 for (j
=i
; j
<nSounding
-1; j
++) {
9153 sounding
[j
] = sounding
[j
+1];
9154 waves
[j
] = waves
[j
+1];
9155 filters
[j
] = filters
[j
+1];
9157 filters
[j
] = tempFilt
;
9158 filters
[j
]->clear();
9164 output
+= filters
[i
]->tick( waves
[i
]->tick() );
9170 /***************************************************/
9172 \brief STK echo effect class.
9174 This class implements a echo effect.
9176 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
9178 /***************************************************/
9182 Echo :: Echo(MY_FLOAT longestDelay
)
9185 this->set( longestDelay
);
9194 void Echo :: set( MY_FLOAT max
)
9196 length
= (long)max
+ 2;
9197 MY_FLOAT delay
= delayLine
? delayLine
->getDelay() : length
>>1;
9198 if( delayLine
) delete delayLine
;
9199 delayLine
= new Delay(length
>>1, length
);
9201 this->setDelay(delay
+.5);
9204 MY_FLOAT
Echo :: getDelay()
9206 return delayLine
->getDelay();
9209 void Echo :: clear()
9215 void Echo :: setDelay(MY_FLOAT delay
)
9217 MY_FLOAT size
= delay
;
9218 if ( delay
< 0.0 ) {
9219 std::cerr
<< "[chuck](via STK): Echo: setDelay parameter is less than zero!" << std::endl
;
9222 else if ( delay
> length
) {
9223 std::cerr
<< "[chuck](via STK): Echo: setDelay parameter is greater than delay length!" << std::endl
;
9227 delayLine
->setDelay((long)size
);
9230 void Echo :: setEffectMix(MY_FLOAT mix
)
9234 std::cerr
<< "[chuck](via STK): Echo: setEffectMix parameter is less than zero!" << std::endl
;
9237 else if ( mix
> 1.0 ) {
9238 std::cerr
<< "[chuck](via STK): Echo: setEffectMix parameter is greater than 1.0!" << std::endl
;
9243 MY_FLOAT
Echo :: lastOut() const
9248 MY_FLOAT
Echo :: tick(MY_FLOAT input
)
9250 lastOutput
= effectMix
* delayLine
->tick(input
);
9251 lastOutput
+= input
* (1.0 - effectMix
);
9255 MY_FLOAT
*Echo :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
9257 for (unsigned int i
=0; i
<vectorSize
; i
++)
9258 vector
[i
] = tick(vector
[i
]);
9262 /***************************************************/
9264 \brief STK envelope base class.
9266 This class implements a simple envelope
9267 generator which is capable of ramping to
9268 a target value by a specified \e rate.
9269 It also responds to simple \e keyOn and
9270 \e keyOff messages, ramping to 1.0 on
9271 keyOn and to 0.0 on keyOff.
9273 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
9275 /***************************************************/
9279 Envelope :: Envelope(void) : Stk()
9281 target
= (MY_FLOAT
) 0.0;
9282 value
= (MY_FLOAT
) 0.0;
9283 rate
= (MY_FLOAT
) 0.001;
9287 Envelope :: ~Envelope(void)
9291 void Envelope :: keyOn(void)
9293 target
= (MY_FLOAT
) 1.0;
9294 if (value
!= target
) state
= 1;
9297 void Envelope :: keyOff(void)
9299 target
= (MY_FLOAT
) 0.0;
9300 if (value
!= target
) state
= 1;
9303 void Envelope :: setRate(MY_FLOAT aRate
)
9306 printf("[chuck](via Envelope): negative rates not allowed ... correcting!\n");
9313 void Envelope :: setTime(MY_FLOAT aTime
)
9316 printf("[chuck](via Envelope): negative times not allowed ... correcting!\n");
9317 rate
= 1.0 / (-aTime
* Stk::sampleRate());
9320 rate
= 1.0 / (aTime
* Stk::sampleRate());
9323 void Envelope :: setTarget(MY_FLOAT aTarget
)
9326 if (value
!= target
) state
= 1;
9329 void Envelope :: setValue(MY_FLOAT aValue
)
9336 int Envelope :: getState(void) const
9341 MY_FLOAT
Envelope :: tick(void)
9344 if (target
> value
) {
9346 if (value
>= target
) {
9353 if (value
<= target
) {
9362 MY_FLOAT
*Envelope :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
9364 for (unsigned int i
=0; i
<vectorSize
; i
++)
9370 MY_FLOAT
Envelope :: lastOut(void) const
9375 /***************************************************/
9377 \brief STK abstract FM synthesis base class.
9379 This class controls an arbitrary number of
9380 waves and envelopes, determined via a
9381 constructor argument.
9383 Control Change Numbers:
9388 - ADSR 2 & 4 Target = 128
9390 The basic Chowning/Stanford FM patent expired
9391 in 1995, but there exist follow-on patents,
9392 mostly assigned to Yamaha. If you are of the
9393 type who should worry about this (making
9396 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
9398 /***************************************************/
9402 FM :: FM(int operators
)
9403 : nOperators(operators
)
9405 if ( nOperators
<= 0 ) {
9407 sprintf(msg
, "[chuck](via FM): Invalid number of operators (%d) argument to constructor!", operators
);
9408 handleError(msg
, StkError::FUNCTION_ARGUMENT
);
9411 twozero
= new TwoZero();
9412 twozero
->setB2( -1.0 );
9413 twozero
->setGain( 0.0 );
9415 // Concatenate the STK rawwave path to the rawwave file
9416 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
9417 vibrato
->setFrequency(6.0);
9420 ratios
= (MY_FLOAT
*) new MY_FLOAT
[nOperators
];
9421 gains
= (MY_FLOAT
*) new MY_FLOAT
[nOperators
];
9422 adsr
= (ADSR
**) calloc( nOperators
, sizeof(ADSR
*) );
9423 waves
= (WaveLoop
**) calloc( nOperators
, sizeof(WaveLoop
*) );
9424 for (i
=0; i
<nOperators
; i
++ ) {
9427 adsr
[i
] = new ADSR();
9430 modDepth
= (MY_FLOAT
) 0.0;
9431 control1
= (MY_FLOAT
) 1.0;
9432 control2
= (MY_FLOAT
) 1.0;
9433 baseFrequency
= (MY_FLOAT
) 440.0;
9435 MY_FLOAT temp
= 1.0;
9436 for (i
=99; i
>=0; i
--) {
9437 __FM_gains
[i
] = temp
;
9442 for (i
=15; i
>=0; i
--) {
9443 __FM_susLevels
[i
] = temp
;
9448 for (i
=0; i
<32; i
++) {
9449 __FM_attTimes
[i
] = temp
;
9461 for (int i
=0; i
<nOperators
; i
++ ) {
9470 void FM :: loadWaves(const char **filenames
)
9472 for (int i
=0; i
<nOperators
; i
++ )
9473 waves
[i
] = new WaveLoop( filenames
[i
], TRUE
);
9476 void FM :: setFrequency(MY_FLOAT frequency
)
9478 baseFrequency
= frequency
;
9480 for (int i
=0; i
<nOperators
; i
++ )
9481 waves
[i
]->setFrequency( baseFrequency
* ratios
[i
] );
9484 void FM :: setRatio(int waveIndex
, MY_FLOAT ratio
)
9486 if ( waveIndex
< 0 ) {
9487 std::cerr
<< "[chuck](via STK): FM: setRatio waveIndex parameter is less than zero!" << std::endl
;
9490 else if ( waveIndex
>= nOperators
) {
9491 std::cerr
<< "[chuck](via STK): FM: setRatio waveIndex parameter is greater than the number of operators!" << std::endl
;
9495 ratios
[waveIndex
] = ratio
;
9497 waves
[waveIndex
]->setFrequency(baseFrequency
* ratio
);
9499 waves
[waveIndex
]->setFrequency(ratio
);
9502 void FM :: setGain(int waveIndex
, MY_FLOAT gain
)
9504 if ( waveIndex
< 0 ) {
9505 std::cerr
<< "[chuck](via STK): FM: setGain waveIndex parameter is less than zero!" << std::endl
;
9508 else if ( waveIndex
>= nOperators
) {
9509 std::cerr
<< "[chuck](via STK): FM: setGain waveIndex parameter is greater than the number of operators!" << std::endl
;
9513 gains
[waveIndex
] = gain
;
9516 void FM :: setModulationSpeed(MY_FLOAT mSpeed
)
9518 vibrato
->setFrequency(mSpeed
);
9521 void FM :: setModulationDepth(MY_FLOAT mDepth
)
9526 void FM :: setControl1(MY_FLOAT cVal
)
9528 control1
= cVal
* (MY_FLOAT
) 2.0;
9531 void FM :: setControl2(MY_FLOAT cVal
)
9533 control2
= cVal
* (MY_FLOAT
) 2.0;
9538 for (int i
=0; i
<nOperators
; i
++ )
9544 for (int i
=0; i
<nOperators
; i
++ )
9548 void FM :: noteOff(MY_FLOAT amplitude
)
9552 #if defined(_STK_DEBUG_)
9553 std::cerr
<< "[chuck](via STK): FM: NoteOff amplitude = " << amplitude
<< std::endl
;
9557 void FM :: controlChange(int number
, MY_FLOAT value
)
9559 MY_FLOAT norm
= value
* ONE_OVER_128
;
9562 std::cerr
<< "[chuck](via STK): FM: Control value less than zero!" << std::endl
;
9564 else if ( norm
> 1.0 ) {
9566 std::cerr
<< "[chuck](via STK): FM: Control value greater than 128.0!" << std::endl
;
9569 if (number
== __SK_Breath_
) // 2
9570 setControl1( norm
);
9571 else if (number
== __SK_FootControl_
) // 4
9572 setControl2( norm
);
9573 else if (number
== __SK_ModFrequency_
) // 11
9574 setModulationSpeed( norm
* 12.0);
9575 else if (number
== __SK_ModWheel_
) // 1
9576 setModulationDepth( norm
);
9577 else if (number
== __SK_AfterTouch_Cont_
) { // 128
9578 //adsr[0]->setTarget( norm );
9579 adsr
[1]->setTarget( norm
);
9580 //adsr[2]->setTarget( norm );
9581 adsr
[3]->setTarget( norm
);
9584 std::cerr
<< "[chuck](via STK): FM: Undefined Control Number (" << number
<< ")!!" << std::endl
;
9586 #if defined(_STK_DEBUG_)
9587 std::cerr
<< "[chuck](via STK): FM: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
9591 /***************************************************/
9593 \brief STK singing FM synthesis instrument.
9595 This class implements 3 carriers and a common
9596 modulator, also referred to as algorithm 6 of
9606 Control Change Numbers:
9611 - ADSR 2 & 4 Target = 128
9613 The basic Chowning/Stanford FM patent expired
9614 in 1995, but there exist follow-on patents,
9615 mostly assigned to Yamaha. If you are of the
9616 type who should worry about this (making
9619 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
9621 /***************************************************/
9624 FMVoices :: FMVoices()
9627 // Concatenate the STK rawwave path to the rawwave files
9628 for ( int i
=0; i
<3; i
++ )
9629 waves
[i
] = new WaveLoop( "special:sinewave", TRUE
);
9630 waves
[3] = new WaveLoop( "special:fwavblnk", TRUE
);
9632 this->setRatio(0, 2.00);
9633 this->setRatio(1, 4.00);
9634 this->setRatio(2, 12.0);
9635 this->setRatio(3, 1.00);
9637 gains
[3] = __FM_gains
[80];
9639 adsr
[0]->setAllTimes( 0.05, 0.05, __FM_susLevels
[15], 0.05);
9640 adsr
[1]->setAllTimes( 0.05, 0.05, __FM_susLevels
[15], 0.05);
9641 adsr
[2]->setAllTimes( 0.05, 0.05, __FM_susLevels
[15], 0.05);
9642 adsr
[3]->setAllTimes( 0.01, 0.01, __FM_susLevels
[15], 0.5);
9644 twozero
->setGain( 0.0 );
9645 modDepth
= (MY_FLOAT
) 0.005;
9653 baseFrequency
= 110.0;
9654 setFrequency( 110.0 );
9657 FMVoices :: ~FMVoices()
9661 void FMVoices :: setFrequency(MY_FLOAT frequency
)
9663 MY_FLOAT temp
, temp2
= 0.0;
9667 if (currentVowel
< 32) {
9669 temp2
= (MY_FLOAT
) 0.9;
9671 else if (currentVowel
< 64) {
9672 i
= currentVowel
- 32;
9673 temp2
= (MY_FLOAT
) 1.0;
9675 else if (currentVowel
< 96) {
9676 i
= currentVowel
- 64;
9677 temp2
= (MY_FLOAT
) 1.1;
9679 else if (currentVowel
<= 128) {
9680 i
= currentVowel
- 96;
9681 temp2
= (MY_FLOAT
) 1.2;
9684 baseFrequency
= frequency
;
9685 temp
= (temp2
* Phonemes::formantFrequency(i
, 0) / baseFrequency
) + 0.5;
9687 this->setRatio(0,(MY_FLOAT
) tempi
);
9688 temp
= (temp2
* Phonemes::formantFrequency(i
, 1) / baseFrequency
) + 0.5;
9690 this->setRatio(1,(MY_FLOAT
) tempi
);
9691 temp
= (temp2
* Phonemes::formantFrequency(i
, 2) / baseFrequency
) + 0.5;
9693 this->setRatio(2, (MY_FLOAT
) tempi
);
9699 void FMVoices :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
9701 this->setFrequency(frequency
);
9702 tilt
[0] = amplitude
;
9703 tilt
[1] = amplitude
* amplitude
;
9704 tilt
[2] = tilt
[1] * amplitude
;
9707 #if defined(_STK_DEBUG_)
9708 std::cerr
<< "[chuck](via STK): FMVoices: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
9712 MY_FLOAT
FMVoices :: tick()
9714 register MY_FLOAT temp
, temp2
;
9716 temp
= gains
[3] * adsr
[3]->tick() * waves
[3]->tick();
9717 temp2
= vibrato
->tick() * modDepth
* (MY_FLOAT
) 0.1;
9719 waves
[0]->setFrequency(baseFrequency
* (1.0 + temp2
) * ratios
[0]);
9720 waves
[1]->setFrequency(baseFrequency
* (1.0 + temp2
) * ratios
[1]);
9721 waves
[2]->setFrequency(baseFrequency
* (1.0 + temp2
) * ratios
[2]);
9722 waves
[3]->setFrequency(baseFrequency
* (1.0 + temp2
) * ratios
[3]);
9724 waves
[0]->addPhaseOffset(temp
* mods
[0]);
9725 waves
[1]->addPhaseOffset(temp
* mods
[1]);
9726 waves
[2]->addPhaseOffset(temp
* mods
[2]);
9727 waves
[3]->addPhaseOffset(twozero
->lastOut());
9728 twozero
->tick(temp
);
9729 temp
= gains
[0] * tilt
[0] * adsr
[0]->tick() * waves
[0]->tick();
9730 temp
+= gains
[1] * tilt
[1] * adsr
[1]->tick() * waves
[1]->tick();
9731 temp
+= gains
[2] * tilt
[2] * adsr
[2]->tick() * waves
[2]->tick();
9736 void FMVoices :: controlChange(int number
, MY_FLOAT value
)
9738 MY_FLOAT norm
= value
* ONE_OVER_128
;
9741 std::cerr
<< "[chuck](via STK): FMVoices: Control value less than zero!" << std::endl
;
9743 else if ( norm
> 1.0 ) {
9745 std::cerr
<< "[chuck](via STK): FMVoices: Control value greater than 128.0!" << std::endl
;
9749 if (number
== __SK_Breath_
) // 2
9750 gains
[3] = __FM_gains
[(int) ( norm
* 99.9 )];
9751 else if (number
== __SK_FootControl_
) { // 4
9752 currentVowel
= (int) (norm
* 128.0);
9753 this->setFrequency(baseFrequency
);
9755 else if (number
== __SK_ModFrequency_
) // 11
9756 this->setModulationSpeed( norm
* 12.0);
9757 else if (number
== __SK_ModWheel_
) // 1
9758 this->setModulationDepth( norm
);
9759 else if (number
== __SK_AfterTouch_Cont_
) { // 128
9761 tilt
[1] = norm
* norm
;
9762 tilt
[2] = tilt
[1] * norm
;
9765 std::cerr
<< "[chuck](via STK): FMVoices: Undefined Control Number (" << number
<< ")!!" << std::endl
;
9767 #if defined(_STK_DEBUG_)
9768 std::cerr
<< "[chuck](via STK): FMVoices: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
9771 /***************************************************/
9773 \brief STK filter class.
9775 This class implements a generic structure which
9776 can be used to create a wide range of filters.
9777 It can function independently or be subclassed
9778 to provide more specific controls based on a
9779 particular filter type.
9781 In particular, this class implements the standard
9782 difference equation:
9784 a[0]*y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb] -
9785 a[1]*y[n-1] - ... - a[na]*y[n-na]
9787 If a[0] is not equal to 1, the filter coeffcients
9788 are normalized by a[0].
9790 The \e gain parameter is applied at the filter
9791 input and does not affect the coefficient values.
9792 The default gain value is 1.0. This structure
9793 results in one extra multiply per computed sample,
9794 but allows easy control of the overall filter gain.
9796 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
9798 /***************************************************/
9804 // The default constructor should setup for pass-through.
9808 b
= new MY_FLOAT
[nB
];
9810 a
= new MY_FLOAT
[nA
];
9813 inputs
= new MY_FLOAT
[nB
];
9814 outputs
= new MY_FLOAT
[nA
];
9818 Filter :: Filter(int nb
, MY_FLOAT
*bCoefficients
, int na
, MY_FLOAT
*aCoefficients
)
9822 // Check the arguments.
9823 if ( nb
< 1 || na
< 1 ) {
9824 sprintf(message
, "[chuck](via Filter): nb (%d) and na (%d) must be >= 1!", nb
, na
);
9825 handleError( message
, StkError::FUNCTION_ARGUMENT
);
9828 if ( aCoefficients
[0] == 0.0 ) {
9829 sprintf(message
, "[chuck](via Filter): a[0] coefficient cannot == 0!");
9830 handleError( message
, StkError::FUNCTION_ARGUMENT
);
9836 b
= new MY_FLOAT
[nB
];
9837 a
= new MY_FLOAT
[nA
];
9839 inputs
= new MY_FLOAT
[nB
];
9840 outputs
= new MY_FLOAT
[nA
];
9843 this->setCoefficients(nB
, bCoefficients
, nA
, aCoefficients
);
9854 void Filter :: clear(void)
9857 for (i
=0; i
<nB
; i
++)
9859 for (i
=0; i
<nA
; i
++)
9863 void Filter :: setCoefficients(int nb
, MY_FLOAT
*bCoefficients
, int na
, MY_FLOAT
*aCoefficients
)
9868 // Check the arguments.
9869 if ( nb
< 1 || na
< 1 ) {
9870 sprintf(message
, "[chuck](via Filter): nb (%d) and na (%d) must be >= 1!", nb
, na
);
9871 handleError( message
, StkError::FUNCTION_ARGUMENT
);
9874 if ( aCoefficients
[0] == 0.0 ) {
9875 sprintf(message
, "[chuck](via Filter): a[0] coefficient cannot == 0!");
9876 handleError( message
, StkError::FUNCTION_ARGUMENT
);
9883 b
= new MY_FLOAT
[nB
];
9884 inputs
= new MY_FLOAT
[nB
];
9885 for (i
=0; i
<nB
; i
++) inputs
[i
] = 0.0;
9892 a
= new MY_FLOAT
[nA
];
9893 outputs
= new MY_FLOAT
[nA
];
9894 for (i
=0; i
<nA
; i
++) outputs
[i
] = 0.0;
9897 for (i
=0; i
<nB
; i
++)
9898 b
[i
] = bCoefficients
[i
];
9899 for (i
=0; i
<nA
; i
++)
9900 a
[i
] = aCoefficients
[i
];
9902 // scale coefficients by a[0] if necessary
9904 for (i
=0; i
<nB
; i
++)
9906 for (i
=0; i
<nA
; i
++)
9911 void Filter :: setNumerator(int nb
, MY_FLOAT
*bCoefficients
)
9916 // Check the arguments.
9918 sprintf(message
, "[chuck](via Filter): nb (%d) must be >= 1!", nb
);
9919 handleError( message
, StkError::FUNCTION_ARGUMENT
);
9926 b
= new MY_FLOAT
[nB
];
9927 inputs
= new MY_FLOAT
[nB
];
9928 for (i
=0; i
<nB
; i
++) inputs
[i
] = 0.0;
9931 for (i
=0; i
<nB
; i
++)
9932 b
[i
] = bCoefficients
[i
];
9935 void Filter :: setDenominator(int na
, MY_FLOAT
*aCoefficients
)
9940 // Check the arguments.
9942 sprintf(message
, "[chuck](via Filter): na (%d) must be >= 1!", na
);
9943 handleError( message
, StkError::FUNCTION_ARGUMENT
);
9946 if ( aCoefficients
[0] == 0.0 ) {
9947 sprintf(message
, "[chuck](via Filter): a[0] coefficient cannot == 0!");
9948 handleError( message
, StkError::FUNCTION_ARGUMENT
);
9955 a
= new MY_FLOAT
[nA
];
9956 outputs
= new MY_FLOAT
[nA
];
9957 for (i
=0; i
<nA
; i
++) outputs
[i
] = 0.0;
9960 for (i
=0; i
<nA
; i
++)
9961 a
[i
] = aCoefficients
[i
];
9963 // scale coefficients by a[0] if necessary
9966 for (i
=0; i
<nB
; i
++)
9968 for (i
=0; i
<nA
; i
++)
9973 void Filter :: setGain(MY_FLOAT theGain
)
9978 MY_FLOAT
Filter :: getGain(void) const
9983 MY_FLOAT
Filter :: lastOut(void) const
9988 MY_FLOAT
Filter :: tick(MY_FLOAT sample
)
9993 inputs
[0] = gain
* sample
;
9994 for (i
=nB
-1; i
>0; i
--) {
9995 outputs
[0] += b
[i
] * inputs
[i
];
9996 inputs
[i
] = inputs
[i
-1];
9998 outputs
[0] += b
[0] * inputs
[0];
10000 for (i
=nA
-1; i
>0; i
--) {
10001 outputs
[0] += -a
[i
] * outputs
[i
];
10002 outputs
[i
] = outputs
[i
-1];
10008 MY_FLOAT
*Filter :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
10010 for (unsigned int i
=0; i
<vectorSize
; i
++)
10011 vector
[i
] = tick(vector
[i
]);
10015 /***************************************************/
10017 \brief STK flute physical model class.
10019 This class implements a simple flute
10020 physical model, as discussed by Karjalainen,
10021 Smith, Waryznyk, etc. The jet model uses
10022 a polynomial, a la Cook.
10024 This is a digital waveguide model, making its
10025 use possibly subject to patents held by Stanford
10026 University, Yamaha, and others.
10028 Control Change Numbers:
10031 - Vibrato Frequency = 11
10033 - Breath Pressure = 128
10035 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
10037 /***************************************************/
10040 Flute :: Flute(MY_FLOAT lowestFrequency
)
10042 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
10043 boreDelay
= new DelayL( 100.0, length
);
10045 jetDelay
= new DelayL( 49.0, length
);
10046 jetTable
= new JetTabl();
10047 filter
= new OnePole();
10048 dcBlock
= new PoleZero();
10049 dcBlock
->setBlockZero();
10050 noise
= new Noise();
10053 // Concatenate the STK rawwave path to the rawwave file
10054 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
10055 vibrato
->setFrequency( 5.925 );
10059 filter
->setPole( 0.7 - ((MY_FLOAT
) 0.1 * 22050.0 / Stk::sampleRate() ) );
10060 filter
->setGain( -1.0 );
10061 adsr
->setAllTimes( 0.005, 0.01, 0.8, 0.010);
10062 endReflection
= (MY_FLOAT
) 0.5;
10063 jetReflection
= (MY_FLOAT
) 0.5;
10064 noiseGain
= 0.15; // Breath pressure random component.
10065 vibratoGain
= (MY_FLOAT
) 0.05; // Breath periodic vibrato component.
10066 jetRatio
= (MY_FLOAT
) 0.32;
10068 maxPressure
= (MY_FLOAT
) 0.0;
10069 lastFrequency
= 220.0;
10084 void Flute :: clear()
10087 boreDelay
->clear();
10092 void Flute :: setFrequency(MY_FLOAT frequency
)
10094 lastFrequency
= frequency
;
10095 if ( frequency
<= 0.0 ) {
10096 std::cerr
<< "[chuck](via STK): Flute: setFrequency parameter is less than or equal to zero!" << std::endl
;
10097 lastFrequency
= 220.0;
10100 // We're overblowing here.
10101 lastFrequency
*= 0.66666;
10102 // Delay = length - approximate filter delay.
10103 MY_FLOAT delay
= Stk::sampleRate() / lastFrequency
- (MY_FLOAT
) 2.0;
10104 if (delay
<= 0.0) delay
= 0.3;
10105 else if (delay
> length
) delay
= length
;
10107 boreDelay
->setDelay(delay
);
10108 jetDelay
->setDelay(delay
* jetRatio
);
10111 void Flute :: startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
10113 fprintf (stderr
,"flute::startblowing %f %f \n", amplitude
, rate
);
10114 adsr
->setAttackRate(rate
);
10115 maxPressure
= amplitude
/ (MY_FLOAT
) 0.8;
10119 void Flute :: stopBlowing(MY_FLOAT rate
)
10121 adsr
->setReleaseRate(rate
);
10125 void Flute :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
10127 setFrequency(frequency
);
10128 startBlowing( 1.1 + (amplitude
* 0.20), amplitude
* 0.02);
10129 outputGain
= amplitude
+ 0.001;
10131 #if defined(_STK_DEBUG_)
10132 std::cerr
<< "[chuck](via STK): Flute: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
10136 void Flute :: noteOff(MY_FLOAT amplitude
)
10138 this->stopBlowing(amplitude
* 0.02);
10140 #if defined(_STK_DEBUG_)
10141 std::cerr
<< "[chuck](via STK): Flute: NoteOff amplitude = " << amplitude
<< std::endl
;
10145 void Flute :: setJetReflection(MY_FLOAT coefficient
)
10147 jetReflection
= coefficient
;
10150 void Flute :: setEndReflection(MY_FLOAT coefficient
)
10152 endReflection
= coefficient
;
10155 void Flute :: setJetDelay(MY_FLOAT aRatio
)
10157 // Delay = length - approximate filter delay.
10158 MY_FLOAT temp
= Stk::sampleRate() / lastFrequency
- (MY_FLOAT
) 2.0;
10160 jetDelay
->setDelay(temp
* aRatio
); // Scaled by ratio.
10163 MY_FLOAT
Flute :: tick()
10165 MY_FLOAT pressureDiff
;
10166 MY_FLOAT breathPressure
;
10168 // Calculate the breath pressure (envelope + noise + vibrato)
10169 breathPressure
= maxPressure
* adsr
->tick();
10170 breathPressure
+= breathPressure
* noiseGain
* noise
->tick();
10171 breathPressure
+= breathPressure
* vibratoGain
* vibrato
->tick();
10173 MY_FLOAT temp
= filter
->tick( boreDelay
->lastOut() );
10174 temp
= dcBlock
->tick(temp
); // Block DC on reflection.
10176 pressureDiff
= breathPressure
- (jetReflection
* temp
);
10177 pressureDiff
= jetDelay
->tick( pressureDiff
);
10178 pressureDiff
= jetTable
->tick( pressureDiff
) + (endReflection
* temp
);
10179 lastOutput
= (MY_FLOAT
) 0.3 * boreDelay
->tick( pressureDiff
);
10181 lastOutput
*= outputGain
;
10185 void Flute :: controlChange(int number
, MY_FLOAT value
)
10187 MY_FLOAT norm
= value
* ONE_OVER_128
;
10190 std::cerr
<< "[chuck](via STK): Flute: Control value less than zero!" << std::endl
;
10192 else if ( norm
> 1.0 ) {
10194 std::cerr
<< "[chuck](via STK): Flute: Control value greater than 128.0!" << std::endl
;
10197 if (number
== __SK_JetDelay_
) // 2
10198 this->setJetDelay( (MY_FLOAT
) (0.08 + (0.48 * norm
)) );
10199 else if (number
== __SK_NoiseLevel_
) // 4
10200 noiseGain
= ( norm
* 0.4);
10201 else if (number
== __SK_ModFrequency_
) // 11
10202 vibrato
->setFrequency( norm
* 12.0);
10203 else if (number
== __SK_ModWheel_
) // 1
10204 vibratoGain
= ( norm
* 0.4 );
10205 else if (number
== __SK_AfterTouch_Cont_
) // 128
10206 adsr
->setTarget( norm
);
10208 std::cerr
<< "[chuck](via STK): Flute: Undefined Control Number (" << number
<< ")!!" << std::endl
;
10210 #if defined(_STK_DEBUG_)
10211 std::cerr
<< "[chuck](via STK): Flute: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
10214 /***************************************************/
10215 /*! \class FormSwep
10216 \brief STK sweepable formant filter class.
10218 This public BiQuad filter subclass implements
10219 a formant (resonance) which can be "swept"
10220 over time from one frequency setting to another.
10221 It provides methods for controlling the sweep
10222 rate and target frequency.
10224 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
10226 /***************************************************/
10229 FormSwep :: FormSwep() : BiQuad()
10231 frequency
= (MY_FLOAT
) 0.0;
10232 radius
= (MY_FLOAT
) 0.0;
10233 targetGain
= (MY_FLOAT
) 1.0;
10234 targetFrequency
= (MY_FLOAT
) 0.0;
10235 targetRadius
= (MY_FLOAT
) 0.0;
10236 deltaGain
= (MY_FLOAT
) 0.0;
10237 deltaFrequency
= (MY_FLOAT
) 0.0;
10238 deltaRadius
= (MY_FLOAT
) 0.0;
10239 sweepState
= (MY_FLOAT
) 0.0;
10240 sweepRate
= (MY_FLOAT
) 0.002;
10245 FormSwep :: ~FormSwep()
10249 void FormSwep :: setResonance(MY_FLOAT aFrequency
, MY_FLOAT aRadius
)
10253 frequency
= aFrequency
;
10255 BiQuad::setResonance( frequency
, radius
, true );
10258 void FormSwep :: setStates(MY_FLOAT aFrequency
, MY_FLOAT aRadius
, MY_FLOAT aGain
)
10262 if ( frequency
!= aFrequency
|| radius
!= aRadius
)
10263 BiQuad::setResonance( aFrequency
, aRadius
, true );
10265 frequency
= aFrequency
;
10268 targetFrequency
= aFrequency
;
10269 targetRadius
= aRadius
;
10270 targetGain
= aGain
;
10273 void FormSwep :: setTargets(MY_FLOAT aFrequency
, MY_FLOAT aRadius
, MY_FLOAT aGain
)
10276 startFrequency
= frequency
;
10277 startRadius
= radius
;
10279 targetFrequency
= aFrequency
;
10280 targetRadius
= aRadius
;
10281 targetGain
= aGain
;
10282 deltaFrequency
= aFrequency
- frequency
;
10283 deltaRadius
= aRadius
- radius
;
10284 deltaGain
= aGain
- gain
;
10285 sweepState
= (MY_FLOAT
) 0.0;
10288 void FormSwep :: setSweepRate(MY_FLOAT aRate
)
10291 if ( sweepRate
> 1.0 ) sweepRate
= 1.0;
10292 if ( sweepRate
< 0.0 ) sweepRate
= 0.0;
10295 void FormSwep :: setSweepTime(MY_FLOAT aTime
)
10297 sweepRate
= 1.0 / ( aTime
* Stk::sampleRate() );
10298 if ( sweepRate
> 1.0 ) sweepRate
= 1.0;
10299 if ( sweepRate
< 0.0 ) sweepRate
= 0.0;
10302 MY_FLOAT
FormSwep :: tick(MY_FLOAT sample
)
10305 sweepState
+= sweepRate
;
10306 if ( sweepState
>= 1.0 ) {
10307 sweepState
= (MY_FLOAT
) 1.0;
10309 radius
= targetRadius
;
10310 frequency
= targetFrequency
;
10314 radius
= startRadius
+ (deltaRadius
* sweepState
);
10315 frequency
= startFrequency
+ (deltaFrequency
* sweepState
);
10316 gain
= startGain
+ (deltaGain
* sweepState
);
10318 BiQuad::setResonance( frequency
, radius
, true );
10321 return BiQuad::tick( sample
);
10324 MY_FLOAT
*FormSwep :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
10326 for (unsigned int i
=0; i
<vectorSize
; i
++)
10327 vector
[i
] = tick(vector
[i
]);
10331 /***************************************************/
10332 /*! \class HevyMetl
10333 \brief STK heavy metal FM synthesis instrument.
10335 This class implements 3 cascade operators with
10336 feedback modulation, also referred to as
10337 algorithm 3 of the TX81Z.
10339 Algorithm 3 is : 4--\
10340 3-->2-- + -->1-->Out
10342 Control Change Numbers:
10343 - Total Modulator Index = 2
10344 - Modulator Crossfade = 4
10347 - ADSR 2 & 4 Target = 128
10349 The basic Chowning/Stanford FM patent expired
10350 in 1995, but there exist follow-on patents,
10351 mostly assigned to Yamaha. If you are of the
10352 type who should worry about this (making
10355 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
10357 /***************************************************/
10360 HevyMetl :: HevyMetl()
10363 // Concatenate the STK rawwave path to the rawwave files
10364 for ( int i
=0; i
<3; i
++ )
10365 waves
[i
] = new WaveLoop( "special:sinewave", TRUE
);
10366 waves
[3] = new WaveLoop( "special:fwavblnk", TRUE
);
10368 this->setRatio(0, 1.0 * 1.000);
10369 this->setRatio(1, 4.0 * 0.999);
10370 this->setRatio(2, 3.0 * 1.001);
10371 this->setRatio(3, 0.5 * 1.002);
10373 gains
[0] = __FM_gains
[92];
10374 gains
[1] = __FM_gains
[76];
10375 gains
[2] = __FM_gains
[91];
10376 gains
[3] = __FM_gains
[68];
10378 adsr
[0]->setAllTimes( 0.001, 0.001, 1.0, 0.01);
10379 adsr
[1]->setAllTimes( 0.001, 0.010, 1.0, 0.50);
10380 adsr
[2]->setAllTimes( 0.010, 0.005, 1.0, 0.20);
10381 adsr
[3]->setAllTimes( 0.030, 0.010, 0.2, 0.20);
10383 twozero
->setGain( 2.0 );
10384 vibrato
->setFrequency( 5.5 );
10388 HevyMetl :: ~HevyMetl()
10392 void HevyMetl :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
10394 gains
[0] = amplitude
* __FM_gains
[92];
10395 gains
[1] = amplitude
* __FM_gains
[76];
10396 gains
[2] = amplitude
* __FM_gains
[91];
10397 gains
[3] = amplitude
* __FM_gains
[68];
10398 this->setFrequency(frequency
);
10401 #if defined(_STK_DEBUG_)
10402 cerr
<< "HevyMetl: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< endl
;
10406 MY_FLOAT
HevyMetl :: tick()
10408 register MY_FLOAT temp
;
10410 temp
= vibrato
->tick() * modDepth
* 0.2;
10411 waves
[0]->setFrequency(baseFrequency
* (1.0 + temp
) * ratios
[0]);
10412 waves
[1]->setFrequency(baseFrequency
* (1.0 + temp
) * ratios
[1]);
10413 waves
[2]->setFrequency(baseFrequency
* (1.0 + temp
) * ratios
[2]);
10414 waves
[3]->setFrequency(baseFrequency
* (1.0 + temp
) * ratios
[3]);
10416 temp
= gains
[2] * adsr
[2]->tick() * waves
[2]->tick();
10417 waves
[1]->addPhaseOffset(temp
);
10419 waves
[3]->addPhaseOffset(twozero
->lastOut());
10420 temp
= (1.0 - (control2
* 0.5)) * gains
[3] * adsr
[3]->tick() * waves
[3]->tick();
10421 twozero
->tick(temp
);
10423 temp
+= control2
* (MY_FLOAT
) 0.5 * gains
[1] * adsr
[1]->tick() * waves
[1]->tick();
10424 temp
= temp
* control1
;
10426 waves
[0]->addPhaseOffset(temp
);
10427 temp
= gains
[0] * adsr
[0]->tick() * waves
[0]->tick();
10429 lastOutput
= temp
* 0.5;
10432 /***************************************************/
10433 /*! \class Instrmnt
10434 \brief STK instrument abstract base class.
10436 This class provides a common interface for
10437 all STK instruments.
10439 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
10441 /***************************************************/
10444 Instrmnt :: Instrmnt()
10448 Instrmnt :: ~Instrmnt()
10452 void Instrmnt :: setFrequency(MY_FLOAT frequency
)
10454 std::cerr
<< "[chuck](via STK): Instrmnt: virtual setFrequency function call!" << std::endl
;
10457 MY_FLOAT
Instrmnt :: lastOut() const
10462 // Support for stereo output:
10463 MY_FLOAT
Instrmnt :: lastOutLeft(void) const
10465 return 0.5 * lastOutput
;
10468 MY_FLOAT
Instrmnt :: lastOutRight(void) const
10470 return 0.5 * lastOutput
;
10473 MY_FLOAT
*Instrmnt :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
10475 for (unsigned int i
=0; i
<vectorSize
; i
++)
10476 vector
[i
] = tick();
10481 void Instrmnt :: controlChange(int number
, MY_FLOAT value
)
10484 /***************************************************/
10486 \brief John Chowning's reverberator class.
10488 This class is derived from the CLM JCRev
10489 function, which is based on the use of
10490 networks of simple allpass and comb delay
10491 filters. This class implements three series
10492 allpass units, followed by four parallel comb
10493 filters, and two decorrelation delay lines in
10494 parallel at the output.
10496 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
10498 /***************************************************/
10502 JCRev :: JCRev(MY_FLOAT T60
)
10504 // Delay lengths for 44100 Hz sample rate.
10505 int lengths
[9] = {1777, 1847, 1993, 2137, 389, 127, 43, 211, 179};
10506 double scaler
= Stk::sampleRate() / 44100.0;
10509 if ( scaler
!= 1.0 ) {
10510 for (i
=0; i
<9; i
++) {
10511 delay
= (int) floor(scaler
* lengths
[i
]);
10512 if ( (delay
& 1) == 0) delay
++;
10513 while ( !this->isPrime(delay
) ) delay
+= 2;
10514 lengths
[i
] = delay
;
10518 for (i
=0; i
<3; i
++)
10519 allpassDelays
[i
] = new Delay(lengths
[i
+4], lengths
[i
+4]);
10521 for (i
=0; i
<4; i
++) {
10522 combDelays
[i
] = new Delay(lengths
[i
], lengths
[i
]);
10523 combCoefficient
[i
] = pow(10.0,(-3 * lengths
[i
] / (T60
* Stk::sampleRate())));
10526 outLeftDelay
= new Delay(lengths
[7], lengths
[7]);
10527 outRightDelay
= new Delay(lengths
[8], lengths
[8]);
10528 allpassCoefficient
= 0.7;
10535 delete allpassDelays
[0];
10536 delete allpassDelays
[1];
10537 delete allpassDelays
[2];
10538 delete combDelays
[0];
10539 delete combDelays
[1];
10540 delete combDelays
[2];
10541 delete combDelays
[3];
10542 delete outLeftDelay
;
10543 delete outRightDelay
;
10546 void JCRev :: clear()
10548 allpassDelays
[0]->clear();
10549 allpassDelays
[1]->clear();
10550 allpassDelays
[2]->clear();
10551 combDelays
[0]->clear();
10552 combDelays
[1]->clear();
10553 combDelays
[2]->clear();
10554 combDelays
[3]->clear();
10555 outRightDelay
->clear();
10556 outLeftDelay
->clear();
10557 lastOutput
[0] = 0.0;
10558 lastOutput
[1] = 0.0;
10561 MY_FLOAT
JCRev :: tick(MY_FLOAT input
)
10563 MY_FLOAT temp
, temp0
, temp1
, temp2
, temp3
, temp4
, temp5
, temp6
;
10566 temp
= allpassDelays
[0]->lastOut();
10567 temp0
= allpassCoefficient
* temp
;
10569 allpassDelays
[0]->tick(temp0
);
10570 temp0
= -(allpassCoefficient
* temp0
) + temp
;
10572 temp
= allpassDelays
[1]->lastOut();
10573 temp1
= allpassCoefficient
* temp
;
10575 allpassDelays
[1]->tick(temp1
);
10576 temp1
= -(allpassCoefficient
* temp1
) + temp
;
10578 temp
= allpassDelays
[2]->lastOut();
10579 temp2
= allpassCoefficient
* temp
;
10581 allpassDelays
[2]->tick(temp2
);
10582 temp2
= -(allpassCoefficient
* temp2
) + temp
;
10584 temp3
= temp2
+ (combCoefficient
[0] * combDelays
[0]->lastOut());
10585 temp4
= temp2
+ (combCoefficient
[1] * combDelays
[1]->lastOut());
10586 temp5
= temp2
+ (combCoefficient
[2] * combDelays
[2]->lastOut());
10587 temp6
= temp2
+ (combCoefficient
[3] * combDelays
[3]->lastOut());
10589 combDelays
[0]->tick(temp3
);
10590 combDelays
[1]->tick(temp4
);
10591 combDelays
[2]->tick(temp5
);
10592 combDelays
[3]->tick(temp6
);
10594 filtout
= temp3
+ temp4
+ temp5
+ temp6
;
10596 lastOutput
[0] = effectMix
* (outLeftDelay
->tick(filtout
));
10597 lastOutput
[1] = effectMix
* (outRightDelay
->tick(filtout
));
10598 temp
= (1.0 - effectMix
) * input
;
10599 lastOutput
[0] += temp
;
10600 lastOutput
[1] += temp
;
10602 return (lastOutput
[0] + lastOutput
[1]) * 0.5;
10604 /***************************************************/
10606 \brief STK jet table class.
10608 This class implements a flue jet non-linear
10609 function, computed by a polynomial calculation.
10610 Contrary to the name, this is not a "table".
10612 Consult Fletcher and Rossing, Karjalainen,
10613 Cook, and others for more information.
10615 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
10617 /***************************************************/
10620 JetTabl :: JetTabl()
10622 lastOutput
= (MY_FLOAT
) 0.0;
10625 JetTabl :: ~JetTabl()
10629 MY_FLOAT
JetTabl :: lastOut() const
10634 MY_FLOAT
JetTabl :: tick( MY_FLOAT input
)
10636 // Perform "table lookup" using a polynomial
10637 // calculation (x^3 - x), which approximates
10638 // the jet sigmoid behavior.
10639 lastOutput
= input
* (input
* input
- (MY_FLOAT
) 1.0);
10641 // Saturate at +/- 1.0.
10642 if (lastOutput
> 1.0)
10643 lastOutput
= (MY_FLOAT
) 1.0;
10644 if (lastOutput
< -1.0)
10645 lastOutput
= (MY_FLOAT
) -1.0;
10649 MY_FLOAT
*JetTabl :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
10651 for (unsigned int i
=0; i
<vectorSize
; i
++)
10652 vector
[i
] = tick(vector
[i
]);
10656 /***************************************************/
10657 /*! \class Mandolin
10658 \brief STK mandolin instrument model class.
10660 This class inherits from PluckTwo and uses
10661 "commuted synthesis" techniques to model a
10662 mandolin instrument.
10664 This is a digital waveguide model, making its
10665 use possibly subject to patents held by
10666 Stanford University, Yamaha, and others.
10667 Commuted Synthesis, in particular, is covered
10668 by patents, granted, pending, and/or
10669 applied-for. All are assigned to the Board of
10670 Trustees, Stanford University. For
10671 information, contact the Office of Technology
10672 Licensing, Stanford University.
10674 Control Change Numbers:
10676 - Pluck Position = 4
10677 - String Sustain = 11
10678 - String Detuning = 1
10679 - Microphone Position = 128
10681 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
10683 /***************************************************/
10686 Mandolin :: Mandolin(MY_FLOAT lowestFrequency
)
10687 : PluckTwo(lowestFrequency
)
10689 // Concatenate the STK rawwave path to the rawwave files
10690 soundfile
[0] = new WvIn( "special:mand1", TRUE
);
10691 soundfile
[1] = new WvIn( "special:mand1", TRUE
);
10692 soundfile
[2] = new WvIn( "special:mand1", TRUE
);
10693 soundfile
[3] = new WvIn( "special:mand1", TRUE
);
10694 soundfile
[4] = new WvIn( "special:mand1", TRUE
);
10695 soundfile
[5] = new WvIn( "special:mand1", TRUE
);
10696 soundfile
[6] = new WvIn( "special:mand1", TRUE
);
10697 soundfile
[7] = new WvIn( "special:mand1", TRUE
);
10698 soundfile
[8] = new WvIn( "special:mand1", TRUE
);
10699 soundfile
[9] = new WvIn( "special:mand1", TRUE
);
10700 soundfile
[10] = new WvIn( "special:mand1", TRUE
);
10701 soundfile
[11] = new WvIn( "special:mand1", TRUE
);
10706 waveDone
= soundfile
[mic
]->isFinished();
10709 Mandolin :: ~Mandolin()
10711 for ( int i
=0; i
<12; i
++ )
10712 delete soundfile
[i
];
10715 void Mandolin :: pluck(MY_FLOAT amplitude
)
10717 // This function gets interesting, because pluck
10718 // may be longer than string length, so we just
10719 // reset the soundfile and add in the pluck in
10720 // the tick method.
10721 soundfile
[mic
]->reset();
10723 pluckAmplitude
= amplitude
;
10724 if ( amplitude
< 0.0 ) {
10725 std::cerr
<< "[chuck](via STK): Mandolin: pluck amplitude parameter less than zero!" << std::endl
;
10726 pluckAmplitude
= 0.0;
10728 else if ( amplitude
> 1.0 ) {
10729 std::cerr
<< "[chuck](via STK): Mandolin: pluck amplitude parameter greater than 1.0!" << std::endl
;
10730 pluckAmplitude
= 1.0;
10733 // Set the pick position, which puts zeroes at position * length.
10734 combDelay
->setDelay((MY_FLOAT
) 0.5 * pluckPosition
* lastLength
);
10735 dampTime
= (long) lastLength
; // See tick method below.
10738 void Mandolin :: pluck(MY_FLOAT amplitude
, MY_FLOAT position
)
10740 // Pluck position puts zeroes at position * length.
10741 pluckPosition
= position
;
10742 if ( position
< 0.0 ) {
10743 std::cerr
<< "[chuck](via STK): Mandolin: pluck position parameter less than zero!" << std::endl
;
10744 pluckPosition
= 0.0;
10746 else if ( position
> 1.0 ) {
10747 std::cerr
<< "[chuck](via STK): Mandolin: pluck position parameter greater than 1.0!" << std::endl
;
10748 pluckPosition
= 1.0;
10751 this->pluck(amplitude
);
10754 void Mandolin :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
10756 this->setFrequency(frequency
);
10757 this->pluck(amplitude
);
10759 #if defined(_STK_DEBUG_)
10760 std::cerr
<< "[chuck](via STK): Mandolin: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
10764 void Mandolin :: setBodySize(MY_FLOAT size
)
10767 // Scale the commuted body response by its sample rate (22050).
10768 MY_FLOAT rate
= size
* 22050.0 / Stk::sampleRate();
10769 for ( int i
=0; i
<12; i
++ )
10770 soundfile
[i
]->setRate(rate
);
10773 MY_FLOAT
Mandolin :: tick()
10775 MY_FLOAT temp
= 0.0;
10777 // Scale the pluck excitation with comb
10778 // filtering for the duration of the file.
10779 temp
= soundfile
[mic
]->tick() * pluckAmplitude
;
10780 temp
= temp
- combDelay
->tick(temp
);
10781 waveDone
= soundfile
[mic
]->isFinished();
10784 // Damping hack to help avoid overflow on re-plucking.
10785 if ( dampTime
>=0 ) {
10787 // Calculate 1st delay filtered reflection plus pluck excitation.
10788 lastOutput
= delayLine
->tick( filter
->tick( temp
+ (delayLine
->lastOut() * (MY_FLOAT
) 0.7) ) );
10789 // Calculate 2nd delay just like the 1st.
10790 lastOutput
+= delayLine2
->tick( filter2
->tick( temp
+ (delayLine2
->lastOut() * (MY_FLOAT
) 0.7) ) );
10792 else { // No damping hack after 1 period.
10793 // Calculate 1st delay filtered reflection plus pluck excitation.
10794 lastOutput
= delayLine
->tick( filter
->tick( temp
+ (delayLine
->lastOut() * loopGain
) ) );
10795 // Calculate 2nd delay just like the 1st.
10796 lastOutput
+= delayLine2
->tick( filter2
->tick( temp
+ (delayLine2
->lastOut() * loopGain
) ) );
10799 lastOutput
*= (MY_FLOAT
) 0.3;
10803 void Mandolin :: controlChange(int number
, MY_FLOAT value
)
10805 MY_FLOAT norm
= value
* ONE_OVER_128
;
10808 std::cerr
<< "[chuck](via STK): Mandolin: Control value less than zero!" << std::endl
;
10810 else if ( norm
> 1.0 ) {
10812 std::cerr
<< "[chuck](via STK): Mandolin: Control value greater than 128.0!" << std::endl
;
10815 if (number
== __SK_BodySize_
) // 2
10816 this->setBodySize( norm
* 2.0 );
10817 else if (number
== __SK_PickPosition_
) // 4
10818 this->setPluckPosition( norm
);
10819 else if (number
== __SK_StringDamping_
) // 11
10820 this->setBaseLoopGain((MY_FLOAT
) 0.97 + (norm
* (MY_FLOAT
) 0.03));
10821 else if (number
== __SK_StringDetune_
) // 1
10822 this->setDetune((MY_FLOAT
) 1.0 - (norm
* (MY_FLOAT
) 0.1));
10823 else if (number
== __SK_AfterTouch_Cont_
) // 128
10824 mic
= (int) (norm
* 11.0);
10826 std::cerr
<< "[chuck](via STK): Mandolin: Undefined Control Number (" << number
<< ")!!" << std::endl
;
10828 #if defined(_STK_DEBUG_)
10829 std::cerr
<< "[chuck](via STK): Mandolin: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
10832 /***************************************************/
10834 \brief Two-dimensional rectilinear waveguide mesh class.
10836 This class implements a rectilinear,
10837 two-dimensional digital waveguide mesh
10838 structure. For details, see Van Duyne and
10839 Smith, "Physical Modeling with the 2-D Digital
10840 Waveguide Mesh", Proceedings of the 1993
10841 International Computer Music Conference.
10843 This is a digital waveguide model, making its
10844 use possibly subject to patents held by Stanford
10845 University, Yamaha, and others.
10847 Control Change Numbers:
10851 - X-Y Input Position = 1
10853 by Julius Smith, 2000 - 2002.
10854 Revised by Gary Scavone for STK, 2002.
10856 /***************************************************/
10858 #include <stdlib.h>
10860 Mesh2D :: Mesh2D(short nX
, short nY
)
10865 MY_FLOAT pole
= 0.05;
10868 for (i
=0; i
<NYMAX
; i
++) {
10869 filterY
[i
] = new OnePole(pole
);
10870 filterY
[i
]->setGain(0.99);
10873 for (i
=0; i
<NXMAX
; i
++) {
10874 filterX
[i
] = new OnePole(pole
);
10875 filterX
[i
]->setGain(0.99);
10885 Mesh2D :: ~Mesh2D()
10888 for (i
=0; i
<NYMAX
; i
++)
10891 for (i
=0; i
<NXMAX
; i
++)
10895 void Mesh2D :: clear()
10900 for (i
=0; i
<NY
; i
++)
10901 filterY
[i
]->clear();
10903 for (i
=0; i
<NX
; i
++)
10904 filterX
[i
]->clear();
10909 void Mesh2D :: clearMesh()
10912 for (x
=0; x
<NXMAX
-1; x
++) {
10913 for (y
=0; y
<NYMAX
-1; y
++) {
10917 for (x
=0; x
<NXMAX
; x
++) {
10918 for (y
=0; y
<NYMAX
; y
++) {
10933 MY_FLOAT
Mesh2D :: energy()
10935 // Return total energy contained in wave variables Note that some
10936 // energy is also contained in any filter delay elements.
10941 if ( counter
& 1 ) { // Ready for Mesh2D::tick1() to be called.
10942 for (x
=0; x
<NX
; x
++) {
10943 for (y
=0; y
<NY
; y
++) {
10955 else { // Ready for Mesh2D::tick0() to be called.
10956 for (x
=0; x
<NX
; x
++) {
10957 for (y
=0; y
<NY
; y
++) {
10973 void Mesh2D :: setNX(short lenX
)
10977 std::cerr
<< "[chuck](via STK): Mesh2D::setNX(" << lenX
<< "): Minimum length is 2!" << std::endl
;
10980 else if ( lenX
> NXMAX
) {
10981 std::cerr
<< "[chuck](via STK): Mesh2D::setNX(" << lenX
<< "): Maximum length is " << NXMAX
<< "!" << std::endl
;
10986 void Mesh2D :: setNY(short lenY
)
10990 std::cerr
<< "[chuck](via STK): Mesh2D::setNY(" << lenY
<< "): Minimum length is 2!" << std::endl
;
10993 else if ( lenY
> NYMAX
) {
10994 std::cerr
<< "[chuck](via STK): Mesh2D::setNY(" << lenY
<< "): Maximum length is " << NYMAX
<< "!" << std::endl
;
10999 void Mesh2D :: setDecay(MY_FLOAT decayFactor
)
11001 MY_FLOAT gain
= decayFactor
;
11002 if ( decayFactor
< 0.0 ) {
11003 std::cerr
<< "[chuck](via STK): Mesh2D::setDecay decayFactor value is less than 0.0!" << std::endl
;
11006 else if ( decayFactor
> 1.0 ) {
11007 std::cerr
<< "[chuck](via STK): Mesh2D::setDecay decayFactor value is greater than 1.0!" << std::endl
;
11012 for (i
=0; i
<NYMAX
; i
++)
11013 filterY
[i
]->setGain(gain
);
11015 for (i
=0; i
<NXMAX
; i
++)
11016 filterX
[i
]->setGain(gain
);
11019 void Mesh2D :: setInputPosition(MY_FLOAT xFactor
, MY_FLOAT yFactor
)
11021 if ( xFactor
< 0.0 ) {
11022 std::cerr
<< "[chuck](via STK): Mesh2D::setInputPosition xFactor value is less than 0.0!" << std::endl
;
11025 else if ( xFactor
> 1.0 ) {
11026 std::cerr
<< "[chuck](via STK): Mesh2D::setInputPosition xFactor value is greater than 1.0!" << std::endl
;
11030 xInput
= (short) (xFactor
* (NX
- 1));
11032 if ( yFactor
< 0.0 ) {
11033 std::cerr
<< "[chuck](via STK): Mesh2D::setInputPosition yFactor value is less than 0.0!" << std::endl
;
11036 else if ( yFactor
> 1.0 ) {
11037 std::cerr
<< "[chuck](via STK): Mesh2D::setInputPosition yFactor value is greater than 1.0!" << std::endl
;
11041 yInput
= (short) (yFactor
* (NY
- 1));
11044 void Mesh2D :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
11046 // Input at corner.
11047 if ( counter
& 1 ) {
11048 vxp1
[xInput
][yInput
] += amplitude
;
11049 vyp1
[xInput
][yInput
] += amplitude
;
11052 vxp
[xInput
][yInput
] += amplitude
;
11053 vyp
[xInput
][yInput
] += amplitude
;
11056 #if defined(_STK_DEBUG_)
11057 std::cerr
<< "[chuck](via STK): Mesh2D: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
11061 void Mesh2D :: noteOff(MY_FLOAT amplitude
)
11063 #if defined(_STK_DEBUG_)
11064 std::cerr
<< "[chuck](via STK): Mesh2D: NoteOff amplitude = " << amplitude
<< std::endl
;
11068 MY_FLOAT
Mesh2D :: tick(MY_FLOAT input
)
11070 if ( counter
& 1 ) {
11071 vxp1
[xInput
][yInput
] += input
;
11072 vyp1
[xInput
][yInput
] += input
;
11073 lastOutput
= tick1();
11076 vxp
[xInput
][yInput
] += input
;
11077 vyp
[xInput
][yInput
] += input
;
11078 lastOutput
= tick0();
11085 MY_FLOAT
Mesh2D :: tick()
11087 lastOutput
= ((counter
& 1) ? this->tick1() : this->tick0());
11092 #define VSCALE ((MY_FLOAT) (0.5))
11094 MY_FLOAT
Mesh2D :: tick0()
11097 MY_FLOAT outsamp
= 0;
11099 // Update junction velocities.
11100 for (x
=0; x
<NX
-1; x
++) {
11101 for (y
=0; y
<NY
-1; y
++) {
11102 v
[x
][y
] = ( vxp
[x
][y
] + vxm
[x
+1][y
] +
11103 vyp
[x
][y
] + vym
[x
][y
+1] ) * VSCALE
;
11107 // Update junction outgoing waves, using alternate wave-variable buffers.
11108 for (x
=0; x
<NX
-1; x
++) {
11109 for (y
=0; y
<NY
-1; y
++) {
11110 MY_FLOAT vxy
= v
[x
][y
];
11111 // Update positive-going waves.
11112 vxp1
[x
+1][y
] = vxy
- vxm
[x
+1][y
];
11113 vyp1
[x
][y
+1] = vxy
- vym
[x
][y
+1];
11114 // Update minus-going waves.
11115 vxm1
[x
][y
] = vxy
- vxp
[x
][y
];
11116 vym1
[x
][y
] = vxy
- vyp
[x
][y
];
11120 // Loop over velocity-junction boundary faces, update edge
11121 // reflections, with filtering. We're only filtering on one x and y
11122 // edge here and even this could be made much sparser.
11123 for (y
=0; y
<NY
-1; y
++) {
11124 vxp1
[0][y
] = filterY
[y
]->tick(vxm
[0][y
]);
11125 vxm1
[NX
-1][y
] = vxp
[NX
-1][y
];
11127 for (x
=0; x
<NX
-1; x
++) {
11128 vyp1
[x
][0] = filterX
[x
]->tick(vym
[x
][0]);
11129 vym1
[x
][NY
-1] = vyp
[x
][NY
-1];
11132 // Output = sum of outgoing waves at far corner. Note that the last
11133 // index in each coordinate direction is used only with the other
11134 // coordinate indices at their next-to-last values. This is because
11135 // the "unit strings" attached to each velocity node to terminate
11136 // the mesh are not themselves connected together.
11137 outsamp
= vxp
[NX
-1][NY
-2] + vyp
[NX
-2][NY
-1];
11142 MY_FLOAT
Mesh2D :: tick1()
11145 MY_FLOAT outsamp
= 0;
11147 // Update junction velocities.
11148 for (x
=0; x
<NX
-1; x
++) {
11149 for (y
=0; y
<NY
-1; y
++) {
11150 v
[x
][y
] = ( vxp1
[x
][y
] + vxm1
[x
+1][y
] +
11151 vyp1
[x
][y
] + vym1
[x
][y
+1] ) * VSCALE
;
11155 // Update junction outgoing waves,
11156 // using alternate wave-variable buffers.
11157 for (x
=0; x
<NX
-1; x
++) {
11158 for (y
=0; y
<NY
-1; y
++) {
11159 MY_FLOAT vxy
= v
[x
][y
];
11161 // Update positive-going waves.
11162 vxp
[x
+1][y
] = vxy
- vxm1
[x
+1][y
];
11163 vyp
[x
][y
+1] = vxy
- vym1
[x
][y
+1];
11165 // Update minus-going waves.
11166 vxm
[x
][y
] = vxy
- vxp1
[x
][y
];
11167 vym
[x
][y
] = vxy
- vyp1
[x
][y
];
11171 // Loop over velocity-junction boundary faces, update edge
11172 // reflections, with filtering. We're only filtering on one x and y
11173 // edge here and even this could be made much sparser.
11174 for (y
=0; y
<NY
-1; y
++) {
11175 vxp
[0][y
] = filterY
[y
]->tick(vxm1
[0][y
]);
11176 vxm
[NX
-1][y
] = vxp1
[NX
-1][y
];
11178 for (x
=0; x
<NX
-1; x
++) {
11179 vyp
[x
][0] = filterX
[x
]->tick(vym1
[x
][0]);
11180 vym
[x
][NY
-1] = vyp1
[x
][NY
-1];
11183 // Output = sum of outgoing waves at far corner.
11184 outsamp
= vxp1
[NX
-1][NY
-2] + vyp1
[NX
-2][NY
-1];
11189 void Mesh2D :: controlChange(int number
, MY_FLOAT value
)
11191 MY_FLOAT norm
= value
* ONE_OVER_128
;
11194 std::cerr
<< "[chuck](via STK): Mesh2D: Control value less than zero!" << std::endl
;
11196 else if ( norm
> 1.0 ) {
11198 std::cerr
<< "[chuck](via STK): Mesh2D: Control value greater than 128.0!" << std::endl
;
11201 if (number
== 2) // 2
11202 setNX( (short) (norm
* (NXMAX
-2) + 2) );
11203 else if (number
== 4) // 4
11204 setNY( (short) (norm
* (NYMAX
-2) + 2) );
11205 else if (number
== 11) // 11
11206 setDecay( 0.9 + (norm
* 0.1) );
11207 else if (number
== __SK_ModWheel_
) // 1
11208 setInputPosition(norm
, norm
);
11209 else if (number
== __SK_AfterTouch_Cont_
) // 128
11212 std::cerr
<< "[chuck](via STK): Mesh2D: Undefined Control Number (" << number
<< ")!!" << std::endl
;
11214 #if defined(_STK_DEBUG_)
11215 std::cerr
<< "[chuck](via STK): Mesh2D: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
11218 /***************************************************/
11220 \brief STK resonance model instrument.
11222 This class contains an excitation wavetable,
11223 an envelope, an oscillator, and N resonances
11224 (non-sweeping BiQuad filters), where N is set
11225 during instantiation.
11227 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
11229 /***************************************************/
11231 #include <stdlib.h>
11233 Modal :: Modal(int modes
)
11236 if ( nModes
<= 0 ) {
11238 sprintf(msg
, "[chuck](via Modal): Invalid number of modes (%d) argument to constructor!", modes
);
11239 handleError(msg
, StkError::FUNCTION_ARGUMENT
);
11242 // We don't make the excitation wave here yet, because we don't know
11243 // what it's going to be.
11245 ratios
= (MY_FLOAT
*) new MY_FLOAT
[nModes
];
11246 radii
= (MY_FLOAT
*) new MY_FLOAT
[nModes
];
11247 filters
= (BiQuad
**) calloc( nModes
, sizeof(BiQuad
*) );
11248 for (int i
=0; i
<nModes
; i
++ ) {
11249 filters
[i
] = new BiQuad
;
11250 filters
[i
]->setEqualGainZeroes();
11253 envelope
= new Envelope
;
11254 onepole
= new OnePole
;
11256 // Concatenate the STK rawwave path to the rawwave file
11257 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
11259 // Set some default values.
11260 vibrato
->setFrequency( 6.0 );
11264 baseFrequency
= 440.0;
11268 stickHardness
= 0.5;
11269 strikePosition
= 0.561;
11280 for (int i
=0; i
<nModes
; i
++ ) {
11286 void Modal :: clear()
11289 for (int i
=0; i
<nModes
; i
++ )
11290 filters
[i
]->clear();
11293 void Modal :: setFrequency(MY_FLOAT frequency
)
11295 baseFrequency
= frequency
;
11296 for (int i
=0; i
<nModes
; i
++ )
11297 this->setRatioAndRadius(i
, ratios
[i
], radii
[i
]);
11300 void Modal :: setRatioAndRadius(int modeIndex
, MY_FLOAT ratio
, MY_FLOAT radius
)
11302 if ( modeIndex
< 0 ) {
11303 std::cerr
<< "[chuck](via STK): Modal: setRatioAndRadius modeIndex parameter is less than zero!" << std::endl
;
11306 else if ( modeIndex
>= nModes
) {
11307 std::cerr
<< "[chuck](via STK): Modal: setRatioAndRadius modeIndex parameter is greater than the number of operators!" << std::endl
;
11311 MY_FLOAT nyquist
= Stk::sampleRate() / 2.0;
11314 if (ratio
* baseFrequency
< nyquist
) {
11315 ratios
[modeIndex
] = ratio
;
11319 while (temp
* baseFrequency
> nyquist
) temp
*= (MY_FLOAT
) 0.5;
11320 ratios
[modeIndex
] = temp
;
11321 #if defined(_STK_DEBUG_)
11322 std::cerr
<< "[chuck](via STK): Modal : Aliasing would occur here ... correcting." << std::endl
;
11325 radii
[modeIndex
] = radius
;
11329 temp
= ratio
*baseFrequency
;
11331 filters
[modeIndex
]->setResonance(temp
, radius
);
11334 void Modal :: setMasterGain(MY_FLOAT aGain
)
11336 masterGain
= aGain
;
11339 void Modal :: setDirectGain(MY_FLOAT aGain
)
11341 directGain
= aGain
;
11344 void Modal :: setModeGain(int modeIndex
, MY_FLOAT gain
)
11346 if ( modeIndex
< 0 ) {
11347 std::cerr
<< "[chuck](via STK): Modal: setModeGain modeIndex parameter is less than zero!" << std::endl
;
11350 else if ( modeIndex
>= nModes
) {
11351 std::cerr
<< "[chuck](via STK): Modal: setModeGain modeIndex parameter is greater than the number of operators!" << std::endl
;
11355 filters
[modeIndex
]->setGain(gain
);
11358 void Modal :: strike(MY_FLOAT amplitude
)
11360 MY_FLOAT gain
= amplitude
;
11361 if ( amplitude
< 0.0 ) {
11362 std::cerr
<< "[chuck](via STK): Modal: strike amplitude is less than zero!" << std::endl
;
11365 else if ( amplitude
> 1.0 ) {
11366 std::cerr
<< "[chuck](via STK): Modal: strike amplitude is greater than 1.0!" << std::endl
;
11370 envelope
->setRate(1.0);
11371 envelope
->setTarget(gain
);
11372 onepole
->setPole(1.0 - gain
);
11377 for (int i
=0; i
<nModes
; i
++) {
11381 temp
= ratios
[i
] * baseFrequency
;
11382 filters
[i
]->setResonance(temp
, radii
[i
]);
11386 void Modal :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
11388 this->strike(amplitude
);
11389 this->setFrequency(frequency
);
11391 #if defined(_STK_DEBUG_)
11392 std::cerr
<< "[chuck](via STK): Modal: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
11396 void Modal :: noteOff(MY_FLOAT amplitude
)
11398 // This calls damp, but inverts the meaning of amplitude (high
11399 // amplitude means fast damping).
11400 this->damp(1.0 - (amplitude
* 0.03));
11402 #if defined(_STK_DEBUG_)
11403 std::cerr
<< "[chuck](via STK): Modal: NoteOff amplitude = " << amplitude
<< std::endl
;
11407 void Modal :: damp(MY_FLOAT amplitude
)
11410 for (int i
=0; i
<nModes
; i
++) {
11414 temp
= ratios
[i
] * baseFrequency
;
11415 filters
[i
]->setResonance(temp
, radii
[i
]*amplitude
);
11419 MY_FLOAT
Modal :: tick()
11421 MY_FLOAT temp
= masterGain
* onepole
->tick(wave
->tick() * envelope
->tick());
11423 MY_FLOAT temp2
= 0.0;
11424 for (int i
=0; i
<nModes
; i
++)
11425 temp2
+= filters
[i
]->tick(temp
);
11427 temp2
-= temp2
* directGain
;
11428 temp2
+= directGain
* temp
;
11430 if (vibratoGain
!= 0.0) {
11431 // Calculate AM and apply to master out
11432 temp
= 1.0 + (vibrato
->tick() * vibratoGain
);
11433 temp2
= temp
* temp2
;
11436 lastOutput
= temp2
;
11439 /***************************************************/
11440 /*! \class ModalBar
11441 \brief STK resonant bar instrument class.
11443 This class implements a number of different
11444 struck bar instruments. It inherits from the
11447 Control Change Numbers:
11448 - Stick Hardness = 2
11449 - Stick Position = 4
11450 - Vibrato Gain = 11
11451 - Vibrato Frequency = 7
11452 - Direct Stick Mix = 1
11454 - Modal Presets = 16
11465 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
11467 /***************************************************/
11471 ModalBar :: ModalBar()
11474 // Concatenate the STK rawwave path to the rawwave file
11475 wave
= new WvIn( "special:marmstk1", TRUE
);
11476 wave
->setRate((MY_FLOAT
) 0.5 * 22050.0 / Stk::sampleRate() );
11478 // Set the resonances for preset 0 (marimba).
11482 ModalBar :: ~ModalBar()
11487 void ModalBar :: setStickHardness(MY_FLOAT hardness
)
11489 stickHardness
= hardness
;
11490 if ( hardness
< 0.0 ) {
11491 std::cerr
<< "[chuck](via STK): ModalBar: setStickHardness parameter is less than zero!" << std::endl
;
11492 stickHardness
= 0.0;
11494 else if ( hardness
> 1.0 ) {
11495 std::cerr
<< "[chuck](via STK): ModalBar: setStickHarness parameter is greater than 1.0!" << std::endl
;
11496 stickHardness
= 1.0;
11499 wave
->setRate( (0.25 * (MY_FLOAT
)pow(4.0, stickHardness
)) );
11500 masterGain
= 0.1 + (1.8 * stickHardness
);
11503 void ModalBar :: setStrikePosition(MY_FLOAT position
)
11505 strikePosition
= position
;
11506 if ( position
< 0.0 ) {
11507 std::cerr
<< "[chuck](via STK): ModalBar: setStrikePositions parameter is less than zero!" << std::endl
;
11508 strikePosition
= 0.0;
11510 else if ( position
> 1.0 ) {
11511 std::cerr
<< "[chuck](via STK): ModalBar: setStrikePosition parameter is greater than 1.0!" << std::endl
;
11512 strikePosition
= 1.0;
11515 // Hack only first three modes.
11516 MY_FLOAT temp2
= position
* PI
;
11517 MY_FLOAT temp
= sin(temp2
);
11518 this->setModeGain(0, 0.12 * temp
);
11520 temp
= sin(0.05 + (3.9 * temp2
));
11521 this->setModeGain(1,(MY_FLOAT
) -0.03 * temp
);
11523 temp
= (MY_FLOAT
) sin(-0.05 + (11 * temp2
));
11524 this->setModeGain(2,(MY_FLOAT
) 0.11 * temp
);
11527 void ModalBar :: setPreset(int preset
)
11530 // First line: relative modal frequencies (negative number is
11531 // a fixed mode that doesn't scale with frequency
11532 // Second line: resonances of the modes
11533 // Third line: mode volumes
11534 // Fourth line: stickHardness, strikePosition, and direct stick
11535 // gain (mixed directly into the output
11536 static MY_FLOAT presets
[9][4][4] = {
11537 {{1.0, 3.99, 10.65, -2443}, // Marimba
11538 {0.9996, 0.9994, 0.9994, 0.999},
11539 {0.04, 0.01, 0.01, 0.008},
11540 {0.429688, 0.445312, 0.093750}},
11541 {{1.0, 2.01, 3.9, 14.37}, // Vibraphone
11542 {0.99995, 0.99991, 0.99992, 0.9999},
11543 {0.025, 0.015, 0.015, 0.015 },
11544 {0.390625,0.570312,0.078125}},
11545 {{1.0, 4.08, 6.669, -3725.0}, // Agogo
11546 {0.999, 0.999, 0.999, 0.999},
11547 {0.06, 0.05, 0.03, 0.02},
11548 {0.609375,0.359375,0.140625}},
11549 {{1.0, 2.777, 7.378, 15.377}, // Wood1
11550 {0.996, 0.994, 0.994, 0.99},
11551 {0.04, 0.01, 0.01, 0.008},
11552 {0.460938,0.375000,0.046875}},
11553 {{1.0, 2.777, 7.378, 15.377}, // Reso
11554 {0.99996, 0.99994, 0.99994, 0.9999},
11555 {0.02, 0.005, 0.005, 0.004},
11556 {0.453125,0.250000,0.101562}},
11557 {{1.0, 1.777, 2.378, 3.377}, // Wood2
11558 {0.996, 0.994, 0.994, 0.99},
11559 {0.04, 0.01, 0.01, 0.008},
11560 {0.312500,0.445312,0.109375}},
11561 {{1.0, 1.004, 1.013, 2.377}, // Beats
11562 {0.9999, 0.9999, 0.9999, 0.999},
11563 {0.02, 0.005, 0.005, 0.004},
11564 {0.398438,0.296875,0.070312}},
11565 {{1.0, 4.0, -1320.0, -3960.0}, // 2Fix
11566 {0.9996, 0.999, 0.9994, 0.999},
11567 {0.04, 0.01, 0.01, 0.008},
11568 {0.453125,0.453125,0.070312}},
11569 {{1.0, 1.217, 1.475, 1.729}, // Clump
11570 {0.999, 0.999, 0.999, 0.999},
11571 {0.03, 0.03, 0.03, 0.03 },
11572 {0.390625,0.570312,0.078125}},
11575 int temp
= (preset
% 9);
11576 for (int i
=0; i
<nModes
; i
++) {
11577 this->setRatioAndRadius(i
, presets
[temp
][0][i
], presets
[temp
][1][i
]);
11578 this->setModeGain(i
, presets
[temp
][2][i
]);
11581 this->setStickHardness(presets
[temp
][3][0]);
11582 this->setStrikePosition(presets
[temp
][3][1]);
11583 directGain
= presets
[temp
][3][2];
11585 if (temp
== 1) // vibraphone
11591 void ModalBar :: controlChange(int number
, MY_FLOAT value
)
11593 MY_FLOAT norm
= value
* ONE_OVER_128
;
11596 std::cerr
<< "[chuck](via STK): ModalBar: Control value less than zero!" << std::endl
;
11598 else if ( norm
> 1.0 ) {
11600 std::cerr
<< "[chuck](via STK): ModalBar: Control value greater than 128.0!" << std::endl
;
11603 if (number
== __SK_StickHardness_
) // 2
11604 this->setStickHardness( norm
);
11605 else if (number
== __SK_StrikePosition_
) // 4
11606 this->setStrikePosition( norm
);
11607 else if (number
== __SK_ProphesyRibbon_
) // 16
11608 this->setPreset((int) value
);
11609 else if (number
== __SK_ModWheel_
) // 1
11611 else if (number
== 11) // 11
11612 vibratoGain
= norm
* 0.3;
11613 else if (number
== __SK_ModFrequency_
) // 7
11614 vibrato
->setFrequency( norm
* 12.0 );
11615 else if (number
== __SK_AfterTouch_Cont_
) // 128
11616 envelope
->setTarget( norm
);
11618 std::cerr
<< "[chuck](via STK): ModalBar: Undefined Control Number (" << number
<< ")!!" << std::endl
;
11620 #if defined(_STK_DEBUG_)
11621 std::cerr
<< "[chuck](via STK): ModalBar: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
11624 /***************************************************/
11625 /*! \class Modulate
11626 \brief STK periodic/random modulator.
11628 This class combines random and periodic
11629 modulations to give a nice, natural human
11630 modulation function.
11632 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
11634 /***************************************************/
11637 Modulate :: Modulate()
11639 // Concatenate the STK rawwave path to the rawwave file
11640 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
11641 vibrato
->setFrequency( 6.0 );
11642 vibratoGain
= 0.04;
11644 noise
= new SubNoise(330);
11647 filter
= new OnePole( 0.999 );
11648 filter
->setGain( randomGain
);
11651 Modulate :: ~Modulate()
11658 void Modulate :: reset()
11660 lastOutput
= (MY_FLOAT
) 0.0;
11663 void Modulate :: setVibratoRate(MY_FLOAT aRate
)
11665 vibrato
->setFrequency( aRate
);
11668 void Modulate :: setVibratoGain(MY_FLOAT aGain
)
11670 vibratoGain
= aGain
;
11673 void Modulate :: setRandomGain(MY_FLOAT aGain
)
11675 randomGain
= aGain
;
11676 filter
->setGain( randomGain
);
11679 MY_FLOAT
Modulate :: tick()
11681 // Compute periodic and random modulations.
11682 lastOutput
= vibratoGain
* vibrato
->tick();
11683 lastOutput
+= filter
->tick( noise
->tick() );
11687 MY_FLOAT
*Modulate :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
11689 for (unsigned int i
=0; i
<vectorSize
; i
++)
11690 vector
[i
] = tick();
11695 MY_FLOAT
Modulate :: lastOut() const
11699 /***************************************************/
11701 \brief STK moog-like swept filter sampling synthesis class.
11703 This instrument uses one attack wave, one
11704 looped wave, and an ADSR envelope (inherited
11705 from the Sampler class) and adds two sweepable
11706 formant (FormSwep) filters.
11708 Control Change Numbers:
11710 - Filter Sweep Rate = 4
11711 - Vibrato Frequency = 11
11715 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
11717 /***************************************************/
11722 // Concatenate the STK rawwave path to the rawwave file
11723 attacks
[0] = new WvIn( "special:mandpluk", TRUE
);
11724 loops
[0] = new WaveLoop( "special:impuls20", TRUE
);
11725 loops
[1] = new WaveLoop( "special:sinewave", TRUE
); // vibrato
11726 loops
[1]->setFrequency((MY_FLOAT
) 6.122);
11728 filters
[0] = new FormSwep();
11729 filters
[0]->setTargets( 0.0, 0.7 );
11731 filters
[1] = new FormSwep();
11732 filters
[1]->setTargets( 0.0, 0.7 );
11734 adsr
->setAllTimes((MY_FLOAT
) 0.001,(MY_FLOAT
) 1.5,(MY_FLOAT
) 0.6,(MY_FLOAT
) 0.250);
11735 filterQ
= (MY_FLOAT
) 0.85;
11736 filterRate
= (MY_FLOAT
) 0.0001;
11737 modDepth
= (MY_FLOAT
) 0.0;
11749 void Moog :: setFrequency(MY_FLOAT frequency
)
11751 baseFrequency
= frequency
;
11752 if ( frequency
<= 0.0 ) {
11753 std::cerr
<< "[chuck](via STK): Moog: setFrequency parameter is less than or equal to zero!" << std::endl
;
11754 baseFrequency
= 220.0;
11757 MY_FLOAT rate
= attacks
[0]->getSize() * 0.01 * baseFrequency
/ sampleRate();
11758 attacks
[0]->setRate( rate
);
11759 loops
[0]->setFrequency(baseFrequency
);
11763 void Moog :: noteOn(MY_FLOAT amplitude
) {
11764 noteOn ( baseFrequency
, amplitude
);
11767 void Moog :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
11771 this->setFrequency( frequency
);
11773 attackGain
= amplitude
* (MY_FLOAT
) 0.5;
11774 loopGain
= amplitude
;
11776 temp
= filterQ
+ (MY_FLOAT
) 0.05;
11777 filters
[0]->setStates( 2000.0, temp
);
11778 filters
[1]->setStates( 2000.0, temp
);
11780 temp
= filterQ
+ (MY_FLOAT
) 0.099;
11781 filters
[0]->setTargets( frequency
, temp
);
11782 filters
[1]->setTargets( frequency
, temp
);
11784 filters
[0]->setSweepRate( filterRate
* 22050.0 / Stk::sampleRate() );
11785 filters
[1]->setSweepRate( filterRate
* 22050.0 / Stk::sampleRate() );
11787 #if defined(_STK_DEBUG_)
11788 std::cerr
<< "[chuck](via STK): Moog: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
11792 void Moog :: setModulationSpeed(MY_FLOAT mSpeed
)
11794 loops
[1]->setFrequency(mSpeed
);
11797 void Moog :: setModulationDepth(MY_FLOAT mDepth
)
11799 modDepth
= mDepth
* (MY_FLOAT
) 0.5;
11802 MY_FLOAT
Moog :: tick()
11806 if ( modDepth
!= 0.0 ) {
11807 temp
= loops
[1]->tick() * modDepth
;
11808 loops
[0]->setFrequency( baseFrequency
* (1.0 + temp
) );
11811 temp
= Sampler::tick();
11812 temp
= filters
[0]->tick( temp
);
11813 lastOutput
= filters
[1]->tick( temp
);
11814 return lastOutput
* 3.0;
11817 void Moog :: controlChange(int number
, MY_FLOAT value
)
11819 MY_FLOAT norm
= value
* ONE_OVER_128
;
11822 std::cerr
<< "[chuck](via STK): Moog: Control value less than zero!" << std::endl
;
11824 else if ( norm
> 1.0 ) {
11826 std::cerr
<< "[chuck](via STK): Moog: Control value greater than 128.0!" << std::endl
;
11829 if (number
== __SK_FilterQ_
) // 2
11830 filterQ
= 0.80 + ( 0.1 * norm
);
11831 else if (number
== __SK_FilterSweepRate_
) // 4
11832 filterRate
= norm
* 0.0002;
11833 else if (number
== __SK_ModFrequency_
) // 11
11834 this->setModulationSpeed( norm
* 12.0 );
11835 else if (number
== __SK_ModWheel_
) // 1
11836 this->setModulationDepth( norm
);
11837 else if (number
== __SK_AfterTouch_Cont_
) // 128
11838 adsr
->setTarget( norm
);
11840 std::cerr
<< "[chuck](via STK): Moog: Undefined Control Number (" << number
<< ")!!" << std::endl
;
11842 #if defined(_STK_DEBUG_)
11843 std::cerr
<< "[chuck](via STK): Moog: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
11849 /***************************************************/
11851 \brief CCRMA's NRev reverberator class.
11853 This class is derived from the CLM NRev
11854 function, which is based on the use of
11855 networks of simple allpass and comb delay
11856 filters. This particular arrangement consists
11857 of 6 comb filters in parallel, followed by 3
11858 allpass filters, a lowpass filter, and another
11859 allpass in series, followed by two allpass
11860 filters in parallel with corresponding right
11863 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
11865 /***************************************************/
11869 NRev :: NRev(MY_FLOAT T60
)
11871 int lengths
[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19};
11872 double scaler
= Stk::sampleRate() / 25641.0;
11875 for (i
=0; i
<15; i
++) {
11876 delay
= (int) floor(scaler
* lengths
[i
]);
11877 if ( (delay
& 1) == 0) delay
++;
11878 while ( !this->isPrime(delay
) ) delay
+= 2;
11879 lengths
[i
] = delay
;
11882 for (i
=0; i
<6; i
++) {
11883 combDelays
[i
] = new Delay( lengths
[i
], lengths
[i
]);
11884 combCoefficient
[i
] = pow(10.0, (-3 * lengths
[i
] / (T60
* Stk::sampleRate())));
11887 for (i
=0; i
<8; i
++)
11888 allpassDelays
[i
] = new Delay(lengths
[i
+6], lengths
[i
+6]);
11890 allpassCoefficient
= 0.7;
11898 for (i
=0; i
<6; i
++) delete combDelays
[i
];
11899 for (i
=0; i
<8; i
++) delete allpassDelays
[i
];
11902 void NRev :: clear()
11905 for (i
=0; i
<6; i
++) combDelays
[i
]->clear();
11906 for (i
=0; i
<8; i
++) allpassDelays
[i
]->clear();
11907 lastOutput
[0] = 0.0;
11908 lastOutput
[1] = 0.0;
11909 lowpassState
= 0.0;
11912 MY_FLOAT
NRev :: tick(MY_FLOAT input
)
11914 MY_FLOAT temp
, temp0
, temp1
, temp2
, temp3
;
11918 for (i
=0; i
<6; i
++) {
11919 temp
= input
+ (combCoefficient
[i
] * combDelays
[i
]->lastOut());
11920 temp0
+= combDelays
[i
]->tick(temp
);
11922 for (i
=0; i
<3; i
++) {
11923 temp
= allpassDelays
[i
]->lastOut();
11924 temp1
= allpassCoefficient
* temp
;
11926 allpassDelays
[i
]->tick(temp1
);
11927 temp0
= -(allpassCoefficient
* temp1
) + temp
;
11930 // One-pole lowpass filter.
11931 lowpassState
= 0.7*lowpassState
+ 0.3*temp0
;
11932 temp
= allpassDelays
[3]->lastOut();
11933 temp1
= allpassCoefficient
* temp
;
11934 temp1
+= lowpassState
;
11935 allpassDelays
[3]->tick(temp1
);
11936 temp1
= -(allpassCoefficient
* temp1
) + temp
;
11938 temp
= allpassDelays
[4]->lastOut();
11939 temp2
= allpassCoefficient
* temp
;
11941 allpassDelays
[4]->tick(temp2
);
11942 lastOutput
[0] = effectMix
*(-(allpassCoefficient
* temp2
) + temp
);
11944 temp
= allpassDelays
[5]->lastOut();
11945 temp3
= allpassCoefficient
* temp
;
11947 allpassDelays
[5]->tick(temp3
);
11948 lastOutput
[1] = effectMix
*(-(allpassCoefficient
* temp3
) + temp
);
11950 temp
= (1.0 - effectMix
) * input
;
11951 lastOutput
[0] += temp
;
11952 lastOutput
[1] += temp
;
11954 return (lastOutput
[0] + lastOutput
[1]) * 0.5;
11957 /***************************************************/
11959 \brief STK noise generator.
11961 Generic random number generation using the
11962 C rand() function. The quality of the rand()
11963 function varies from one OS to another.
11965 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
11967 /***************************************************/
11969 #include <stdlib.h>
11972 Noise :: Noise() : Stk()
11974 // Seed the random number generator with system time.
11975 this->setSeed( 0 );
11976 lastOutput
= (MY_FLOAT
) 0.0;
11979 Noise :: Noise( unsigned int seed
) : Stk()
11981 // Seed the random number generator
11982 this->setSeed( seed
);
11983 lastOutput
= (MY_FLOAT
) 0.0;
11990 void Noise :: setSeed( unsigned int seed
)
11993 srand( (unsigned int) time(NULL
) );
11998 MY_FLOAT
Noise :: tick()
12000 lastOutput
= (MY_FLOAT
) (2.0 * rand() / (RAND_MAX
+ 1.0) );
12005 MY_FLOAT
*Noise :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
12007 for (unsigned int i
=0; i
<vectorSize
; i
++)
12008 vector
[i
] = tick();
12013 MY_FLOAT
Noise :: lastOut() const
12018 /***************************************************/
12020 \brief STK one-pole filter class.
12022 This protected Filter subclass implements
12023 a one-pole digital filter. A method is
12024 provided for setting the pole position along
12025 the real axis of the z-plane while maintaining
12026 a constant peak filter gain.
12028 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
12030 /***************************************************/
12033 OnePole :: OnePole() : Filter()
12036 MY_FLOAT A
[2] = {1.0, -0.9};
12037 Filter::setCoefficients( 1, &B
, 2, A
);
12040 OnePole :: OnePole(MY_FLOAT thePole
) : Filter()
12043 MY_FLOAT A
[2] = {1.0, -0.9};
12045 // Normalize coefficients for peak unity gain.
12047 B
= (MY_FLOAT
) (1.0 - thePole
);
12049 B
= (MY_FLOAT
) (1.0 + thePole
);
12052 Filter::setCoefficients( 1, &B
, 2, A
);
12055 OnePole :: ~OnePole()
12059 void OnePole :: clear(void)
12064 void OnePole :: setB0(MY_FLOAT b0
)
12069 void OnePole :: setA1(MY_FLOAT a1
)
12074 void OnePole :: setPole(MY_FLOAT thePole
)
12076 // Normalize coefficients for peak unity gain.
12078 b
[0] = (MY_FLOAT
) (1.0 - thePole
);
12080 b
[0] = (MY_FLOAT
) (1.0 + thePole
);
12085 void OnePole :: setGain(MY_FLOAT theGain
)
12087 Filter::setGain(theGain
);
12090 MY_FLOAT
OnePole :: getGain(void) const
12092 return Filter::getGain();
12095 MY_FLOAT
OnePole :: lastOut(void) const
12097 return Filter::lastOut();
12100 MY_FLOAT
OnePole :: tick(MY_FLOAT sample
)
12102 inputs
[0] = gain
* sample
;
12103 outputs
[0] = b
[0] * inputs
[0] - a
[1] * outputs
[1];
12104 outputs
[1] = outputs
[0];
12109 MY_FLOAT
*OnePole :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
12111 for (unsigned int i
=0; i
<vectorSize
; i
++)
12112 vector
[i
] = tick(vector
[i
]);
12116 /***************************************************/
12118 \brief STK one-zero filter class.
12120 This protected Filter subclass implements
12121 a one-zero digital filter. A method is
12122 provided for setting the zero position
12123 along the real axis of the z-plane while
12124 maintaining a constant filter gain.
12126 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
12128 /***************************************************/
12131 OneZero :: OneZero() : Filter()
12133 MY_FLOAT B
[2] = {0.5, 0.5};
12135 Filter::setCoefficients( 2, B
, 1, &A
);
12138 OneZero :: OneZero(MY_FLOAT theZero
) : Filter()
12143 // Normalize coefficients for unity gain.
12145 B
[0] = 1.0 / ((MY_FLOAT
) 1.0 + theZero
);
12147 B
[0] = 1.0 / ((MY_FLOAT
) 1.0 - theZero
);
12149 B
[1] = -theZero
* B
[0];
12150 Filter::setCoefficients( 2, B
, 1, &A
);
12153 OneZero :: ~OneZero(void)
12157 void OneZero :: clear(void)
12162 void OneZero :: setB0(MY_FLOAT b0
)
12167 void OneZero :: setB1(MY_FLOAT b1
)
12172 void OneZero :: setZero(MY_FLOAT theZero
)
12174 // Normalize coefficients for unity gain.
12176 b
[0] = 1.0 / ((MY_FLOAT
) 1.0 + theZero
);
12178 b
[0] = 1.0 / ((MY_FLOAT
) 1.0 - theZero
);
12180 b
[1] = -theZero
* b
[0];
12183 void OneZero :: setGain(MY_FLOAT theGain
)
12185 Filter::setGain(theGain
);
12188 MY_FLOAT
OneZero :: getGain(void) const
12190 return Filter::getGain();
12193 MY_FLOAT
OneZero :: lastOut(void) const
12195 return Filter::lastOut();
12198 MY_FLOAT
OneZero :: tick(MY_FLOAT sample
)
12200 inputs
[0] = gain
* sample
;
12201 outputs
[0] = b
[1] * inputs
[1] + b
[0] * inputs
[0];
12202 inputs
[1] = inputs
[0];
12207 MY_FLOAT
*OneZero :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
12209 for (unsigned int i
=0; i
<vectorSize
; i
++)
12210 vector
[i
] = tick(vector
[i
]);
12214 /***************************************************/
12216 \brief Perry's simple reverberator class.
12218 This class is based on some of the famous
12219 Stanford/CCRMA reverbs (NRev, KipRev), which
12220 were based on the Chowning/Moorer/Schroeder
12221 reverberators using networks of simple allpass
12222 and comb delay filters. This class implements
12223 two series allpass units and two parallel comb
12226 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
12228 /***************************************************/
12232 PRCRev :: PRCRev(MY_FLOAT T60
)
12234 // Delay lengths for 44100 Hz sample rate.
12235 int lengths
[4]= {353, 1097, 1777, 2137};
12236 double scaler
= Stk::sampleRate() / 44100.0;
12238 // Scale the delay lengths if necessary.
12240 if ( scaler
!= 1.0 ) {
12241 for (i
=0; i
<4; i
++) {
12242 delay
= (int) floor(scaler
* lengths
[i
]);
12243 if ( (delay
& 1) == 0) delay
++;
12244 while ( !this->isPrime(delay
) ) delay
+= 2;
12245 lengths
[i
] = delay
;
12249 for (i
=0; i
<2; i
++) {
12250 allpassDelays
[i
] = new Delay( lengths
[i
], lengths
[i
] );
12251 combDelays
[i
] = new Delay( lengths
[i
+2], lengths
[i
+2] );
12252 combCoefficient
[i
] = pow(10.0,(-3 * lengths
[i
+2] / (T60
* Stk::sampleRate())));
12255 allpassCoefficient
= 0.7;
12260 PRCRev :: ~PRCRev()
12262 delete allpassDelays
[0];
12263 delete allpassDelays
[1];
12264 delete combDelays
[0];
12265 delete combDelays
[1];
12268 void PRCRev :: clear()
12270 allpassDelays
[0]->clear();
12271 allpassDelays
[1]->clear();
12272 combDelays
[0]->clear();
12273 combDelays
[1]->clear();
12274 lastOutput
[0] = 0.0;
12275 lastOutput
[1] = 0.0;
12278 MY_FLOAT
PRCRev :: tick(MY_FLOAT input
)
12280 MY_FLOAT temp
, temp0
, temp1
, temp2
, temp3
;
12282 temp
= allpassDelays
[0]->lastOut();
12283 temp0
= allpassCoefficient
* temp
;
12285 allpassDelays
[0]->tick(temp0
);
12286 temp0
= -(allpassCoefficient
* temp0
) + temp
;
12288 temp
= allpassDelays
[1]->lastOut();
12289 temp1
= allpassCoefficient
* temp
;
12291 allpassDelays
[1]->tick(temp1
);
12292 temp1
= -(allpassCoefficient
* temp1
) + temp
;
12294 temp2
= temp1
+ (combCoefficient
[0] * combDelays
[0]->lastOut());
12295 temp3
= temp1
+ (combCoefficient
[1] * combDelays
[1]->lastOut());
12297 lastOutput
[0] = effectMix
* (combDelays
[0]->tick(temp2
));
12298 lastOutput
[1] = effectMix
* (combDelays
[1]->tick(temp3
));
12299 temp
= (MY_FLOAT
) (1.0 - effectMix
) * input
;
12300 lastOutput
[0] += temp
;
12301 lastOutput
[1] += temp
;
12303 return (lastOutput
[0] + lastOutput
[1]) * (MY_FLOAT
) 0.5;
12306 /***************************************************/
12307 /*! \class PercFlut
12308 \brief STK percussive flute FM synthesis instrument.
12310 This class implements algorithm 4 of the TX81Z.
12313 Algorithm 4 is : 4->3--\
12317 Control Change Numbers:
12318 - Total Modulator Index = 2
12319 - Modulator Crossfade = 4
12322 - ADSR 2 & 4 Target = 128
12324 The basic Chowning/Stanford FM patent expired
12325 in 1995, but there exist follow-on patents,
12326 mostly assigned to Yamaha. If you are of the
12327 type who should worry about this (making
12330 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
12332 /***************************************************/
12335 PercFlut :: PercFlut()
12338 // Concatenate the STK rawwave path to the rawwave files
12339 for ( int i
=0; i
<3; i
++ )
12340 waves
[i
] = new WaveLoop( "special:sinewave", TRUE
);
12341 waves
[3] = new WaveLoop( "special:fwavblnk", TRUE
);
12343 this->setRatio(0, 1.50 * 1.000);
12344 this->setRatio(1, 3.00 * 0.995);
12345 this->setRatio(2, 2.99 * 1.005);
12346 this->setRatio(3, 6.00 * 0.997);
12347 gains
[0] = __FM_gains
[99];
12348 gains
[1] = __FM_gains
[71];
12349 gains
[2] = __FM_gains
[93];
12350 gains
[3] = __FM_gains
[85];
12352 adsr
[0]->setAllTimes( 0.05, 0.05, __FM_susLevels
[14], 0.05);
12353 adsr
[1]->setAllTimes( 0.02, 0.50, __FM_susLevels
[13], 0.5);
12354 adsr
[2]->setAllTimes( 0.02, 0.30, __FM_susLevels
[11], 0.05);
12355 adsr
[3]->setAllTimes( 0.02, 0.05, __FM_susLevels
[13], 0.01);
12357 twozero
->setGain( 0.0 );
12361 PercFlut :: ~PercFlut()
12365 void PercFlut :: setFrequency(MY_FLOAT frequency
)
12367 baseFrequency
= frequency
;
12370 void PercFlut :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
12372 gains
[0] = amplitude
* __FM_gains
[99] * 0.5;
12373 gains
[1] = amplitude
* __FM_gains
[71] * 0.5;
12374 gains
[2] = amplitude
* __FM_gains
[93] * 0.5;
12375 gains
[3] = amplitude
* __FM_gains
[85] * 0.5;
12376 this->setFrequency(frequency
);
12379 #if defined(_STK_DEBUG_)
12380 cerr
<< "PercFlut: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< endl
;
12384 MY_FLOAT
PercFlut :: tick()
12386 register MY_FLOAT temp
;
12388 temp
= vibrato
->tick() * modDepth
* (MY_FLOAT
) 0.2;
12389 waves
[0]->setFrequency(baseFrequency
* ((MY_FLOAT
) 1.0 + temp
) * ratios
[0]);
12390 waves
[1]->setFrequency(baseFrequency
* ((MY_FLOAT
) 1.0 + temp
) * ratios
[1]);
12391 waves
[2]->setFrequency(baseFrequency
* ((MY_FLOAT
) 1.0 + temp
) * ratios
[2]);
12392 waves
[3]->setFrequency(baseFrequency
* ((MY_FLOAT
) 1.0 + temp
) * ratios
[3]);
12394 waves
[3]->addPhaseOffset(twozero
->lastOut());
12395 temp
= gains
[3] * adsr
[3]->tick() * waves
[3]->tick();
12397 twozero
->tick(temp
);
12398 waves
[2]->addPhaseOffset(temp
);
12399 temp
= (1.0 - (control2
* 0.5)) * gains
[2] * adsr
[2]->tick() * waves
[2]->tick();
12401 temp
+= control2
* 0.5 * gains
[1] * adsr
[1]->tick() * waves
[1]->tick();
12402 temp
= temp
* control1
;
12404 waves
[0]->addPhaseOffset(temp
);
12405 temp
= gains
[0] * adsr
[0]->tick() * waves
[0]->tick();
12407 lastOutput
= temp
* (MY_FLOAT
) 0.5;
12410 /***************************************************/
12411 /*! \class Phonemes
12412 \brief STK phonemes table.
12414 This class does nothing other than declare a
12415 set of 32 static phoneme formant parameters
12416 and provide access to those values.
12418 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
12420 /***************************************************/
12422 #include <iostream>
12424 const char Phonemes :: phonemeNames
[32][4] =
12425 {"eee", "ihh", "ehh", "aaa",
12426 "ahh", "aww", "ohh", "uhh",
12427 "uuu", "ooo", "rrr", "lll",
12428 "mmm", "nnn", "nng", "ngg",
12429 "fff", "sss", "thh", "shh",
12430 "xxx", "hee", "hoo", "hah",
12431 "bbb", "ddd", "jjj", "ggg",
12432 "vvv", "zzz", "thz", "zhh"
12435 const MY_FLOAT
Phonemes :: phonemeGains
[32][2] =
12436 {{1.0, 0.0}, // eee
12477 const MY_FLOAT
Phonemes :: phonemeParameters
[32][4][3] =
12478 {{ { 273, 0.996, 10}, // eee (beet)
12479 {2086, 0.945, -16},
12480 {2754, 0.979, -12},
12481 {3270, 0.440, -17}},
12482 { { 385, 0.987, 10}, // ihh (bit)
12483 {2056, 0.930, -20},
12484 {2587, 0.890, -20},
12485 {3150, 0.400, -20}},
12486 { { 515, 0.977, 10}, // ehh (bet)
12487 {1805, 0.810, -10},
12488 {2526, 0.875, -10},
12489 {3103, 0.400, -13}},
12490 { { 773, 0.950, 10}, // aaa (bat)
12492 {2380, 0.880, -20},
12493 {3027, 0.600, -20}},
12495 { { 770, 0.950, 0}, // ahh (father)
12497 {2450, 0.780, -29},
12498 {3140, 0.800, -39}},
12499 { { 637, 0.910, 0}, // aww (bought)
12501 {2556, 0.950, -17},
12502 {3070, 0.910, -20}},
12503 { { 637, 0.910, 0}, // ohh (bone) NOTE:: same as aww (bought)
12505 {2556, 0.950, -17},
12506 {3070, 0.910, -20}},
12507 { { 561, 0.965, 0}, // uhh (but)
12508 {1084, 0.930, -10},
12509 {2541, 0.930, -15},
12510 {3345, 0.900, -20}},
12512 { { 515, 0.976, 0}, // uuu (foot)
12514 {2572, 0.960, -11},
12515 {3345, 0.960, -20}},
12516 { { 349, 0.986, -10}, // ooo (boot)
12517 { 918, 0.940, -20},
12518 {2350, 0.960, -27},
12519 {2731, 0.950, -33}},
12520 { { 394, 0.959, -10}, // rrr (bird)
12521 {1297, 0.780, -16},
12522 {1441, 0.980, -16},
12523 {2754, 0.950, -40}},
12524 { { 462, 0.990, +5}, // lll (lull)
12525 {1200, 0.640, -10},
12526 {2500, 0.200, -20},
12527 {3000, 0.100, -30}},
12529 { { 265, 0.987, -10}, // mmm (mom)
12530 {1176, 0.940, -22},
12531 {2352, 0.970, -20},
12532 {3277, 0.940, -31}},
12533 { { 204, 0.980, -10}, // nnn (nun)
12534 {1570, 0.940, -15},
12535 {2481, 0.980, -12},
12536 {3133, 0.800, -30}},
12537 { { 204, 0.980, -10}, // nng (sang) NOTE:: same as nnn
12538 {1570, 0.940, -15},
12539 {2481, 0.980, -12},
12540 {3133, 0.800, -30}},
12541 { { 204, 0.980, -10}, // ngg (bong) NOTE:: same as nnn
12542 {1570, 0.940, -15},
12543 {2481, 0.980, -12},
12544 {3133, 0.800, -30}},
12546 { {1000, 0.300, 0}, // fff
12547 {2800, 0.860, -10},
12550 { {0, 0.000, 0}, // sss
12551 {2000, 0.700, -15},
12554 { { 100, 0.900, 0}, // thh
12555 {4000, 0.500, -20},
12556 {5500, 0.500, -15},
12557 {8000, 0.400, -20}},
12558 { {2693, 0.940, 0}, // shh
12559 {4000, 0.720, -10},
12560 {6123, 0.870, -10},
12561 {7755, 0.750, -18}},
12563 { {1000, 0.300, -10}, // xxx NOTE:: Not Really Done Yet
12564 {2800, 0.860, -10},
12567 { { 273, 0.996, -40}, // hee (beet) (noisy eee)
12568 {2086, 0.945, -16},
12569 {2754, 0.979, -12},
12570 {3270, 0.440, -17}},
12571 { { 349, 0.986, -40}, // hoo (boot) (noisy ooo)
12572 { 918, 0.940, -10},
12573 {2350, 0.960, -17},
12574 {2731, 0.950, -23}},
12575 { { 770, 0.950, -40}, // hah (father) (noisy ahh)
12577 {2450, 0.780, -20},
12578 {3140, 0.800, -32}},
12580 { {2000, 0.700, -20}, // bbb NOTE:: Not Really Done Yet
12581 {5257, 0.750, -15},
12584 { { 100, 0.900, 0}, // ddd NOTE:: Not Really Done Yet
12585 {4000, 0.500, -20},
12586 {5500, 0.500, -15},
12587 {8000, 0.400, -20}},
12588 { {2693, 0.940, 0}, // jjj NOTE:: Not Really Done Yet
12589 {4000, 0.720, -10},
12590 {6123, 0.870, -10},
12591 {7755, 0.750, -18}},
12592 { {2693, 0.940, 0}, // ggg NOTE:: Not Really Done Yet
12593 {4000, 0.720, -10},
12594 {6123, 0.870, -10},
12595 {7755, 0.750, -18}},
12597 { {2000, 0.700, -20}, // vvv NOTE:: Not Really Done Yet
12598 {5257, 0.750, -15},
12601 { { 100, 0.900, 0}, // zzz NOTE:: Not Really Done Yet
12602 {4000, 0.500, -20},
12603 {5500, 0.500, -15},
12604 {8000, 0.400, -20}},
12605 { {2693, 0.940, 0}, // thz NOTE:: Not Really Done Yet
12606 {4000, 0.720, -10},
12607 {6123, 0.870, -10},
12608 {7755, 0.750, -18}},
12609 { {2693, 0.940, 0}, // zhh NOTE:: Not Really Done Yet
12610 {4000, 0.720, -10},
12611 {6123, 0.870, -10},
12612 {7755, 0.750, -18}}
12615 Phonemes :: Phonemes(void)
12619 Phonemes :: ~Phonemes(void)
12623 const char *Phonemes :: name( unsigned int index
)
12625 if ( index
> 31 ) {
12626 std::cerr
<< "[chuck](via STK): Phonemes: name index is greater than 31!" << std::endl
;
12629 return phonemeNames
[index
];
12632 MY_FLOAT
Phonemes :: voiceGain( unsigned int index
)
12634 if ( index
> 31 ) {
12635 std::cerr
<< "[chuck](via STK): Phonemes: voiceGain index is greater than 31!" << std::endl
;
12638 return phonemeGains
[index
][0];
12641 MY_FLOAT
Phonemes :: noiseGain( unsigned int index
)
12643 if ( index
> 31 ) {
12644 std::cerr
<< "[chuck](via STK): Phonemes: noiseGain index is greater than 31!" << std::endl
;
12647 return phonemeGains
[index
][1];
12650 MY_FLOAT
Phonemes :: formantFrequency( unsigned int index
, unsigned int partial
)
12652 if ( index
> 31 ) {
12653 std::cerr
<< "[chuck](via STK): Phonemes: formantFrequency index is greater than 31!" << std::endl
;
12656 if ( partial
> 3 ) {
12657 std::cerr
<< "[chuck](via STK): Phonemes: formantFrequency partial is greater than 3!" << std::endl
;
12660 return phonemeParameters
[index
][partial
][0];
12663 MY_FLOAT
Phonemes :: formantRadius( unsigned int index
, unsigned int partial
)
12665 if ( index
> 31 ) {
12666 std::cerr
<< "[chuck](via STK): Phonemes: formantRadius index is greater than 31!" << std::endl
;
12669 if ( partial
> 3 ) {
12670 std::cerr
<< "[chuck](via STK): Phonemes: formantRadius partial is greater than 3!" << std::endl
;
12673 return phonemeParameters
[index
][partial
][1];
12676 MY_FLOAT
Phonemes :: formantGain( unsigned int index
, unsigned int partial
)
12678 if ( index
> 31 ) {
12679 std::cerr
<< "[chuck](via STK): Phonemes: formantGain index is greater than 31!" << std::endl
;
12682 if ( partial
> 3 ) {
12683 std::cerr
<< "[chuck](via STK): Phonemes: formantGain partial is greater than 3!" << std::endl
;
12686 return phonemeParameters
[index
][partial
][2];
12688 /***************************************************/
12689 /*! \class PitShift
12690 \brief STK simple pitch shifter effect class.
12692 This class implements a simple pitch shifter
12695 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
12697 /***************************************************/
12699 #include <iostream>
12702 PitShift :: PitShift()
12706 delayLine
[0] = new DelayL(delay
[0], (long) 1024);
12707 delayLine
[1] = new DelayL(delay
[1], (long) 1024);
12708 effectMix
= (MY_FLOAT
) 0.5;
12712 PitShift :: ~PitShift()
12714 delete delayLine
[0];
12715 delete delayLine
[1];
12718 void PitShift :: clear()
12720 delayLine
[0]->clear();
12721 delayLine
[1]->clear();
12725 void PitShift :: setEffectMix(MY_FLOAT mix
)
12729 std::cerr
<< "[chuck](via STK): PitShift: setEffectMix parameter is less than zero!" << std::endl
;
12732 else if ( mix
> 1.0 ) {
12733 std::cerr
<< "[chuck](via STK): PitShift: setEffectMix parameter is greater than 1.0!" << std::endl
;
12738 void PitShift :: setShift(MY_FLOAT shift
)
12741 rate
= 1.0 - shift
;
12743 else if (shift
> 1.0) {
12744 rate
= 1.0 - shift
;
12752 MY_FLOAT
PitShift :: lastOut() const
12757 MY_FLOAT
PitShift :: tick(MY_FLOAT input
)
12759 delay
[0] = delay
[0] + rate
;
12760 while (delay
[0] > 1012) delay
[0] -= 1000;
12761 while (delay
[0] < 12) delay
[0] += 1000;
12762 delay
[1] = delay
[0] + 500;
12763 while (delay
[1] > 1012) delay
[1] -= 1000;
12764 while (delay
[1] < 12) delay
[1] += 1000;
12765 delayLine
[0]->setDelay((long)delay
[0]);
12766 delayLine
[1]->setDelay((long)delay
[1]);
12767 env
[1] = fabs(delay
[0] - 512) * 0.002;
12768 env
[0] = 1.0 - env
[1];
12769 lastOutput
= env
[0] * delayLine
[0]->tick(input
);
12770 lastOutput
+= env
[1] * delayLine
[1]->tick(input
);
12771 lastOutput
*= effectMix
;
12772 lastOutput
+= (1.0 - effectMix
) * input
;
12776 MY_FLOAT
*PitShift :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
12778 for (unsigned int i
=0; i
<vectorSize
; i
++)
12779 vector
[i
] = tick(vector
[i
]);
12784 /***************************************************/
12785 /*! \class PluckTwo
12786 \brief STK enhanced plucked string model class.
12788 This class implements an enhanced two-string,
12789 plucked physical model, a la Jaffe-Smith,
12792 PluckTwo is an abstract class, with no excitation
12793 specified. Therefore, it can't be directly
12796 This is a digital waveguide model, making its
12797 use possibly subject to patents held by
12798 Stanford University, Yamaha, and others.
12800 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
12802 /***************************************************/
12805 PluckTwo :: PluckTwo(MY_FLOAT lowestFrequency
)
12807 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
12808 baseLoopGain
= (MY_FLOAT
) 0.995;
12809 loopGain
= (MY_FLOAT
) 0.999;
12810 delayLine
= new DelayA((MY_FLOAT
)(length
/ 2.0), length
);
12811 delayLine2
= new DelayA((MY_FLOAT
)(length
/ 2.0), length
);
12812 combDelay
= new DelayL((MY_FLOAT
)(length
/ 2.0), length
);
12813 filter
= new OneZero
;
12814 filter2
= new OneZero
;
12815 pluckAmplitude
= (MY_FLOAT
) 0.3;
12816 pluckPosition
= (MY_FLOAT
) 0.4;
12817 detuning
= (MY_FLOAT
) 0.995;
12818 lastFrequency
= lowestFrequency
* (MY_FLOAT
) 2.0;
12819 lastLength
= length
* (MY_FLOAT
) 0.5;
12822 PluckTwo :: ~PluckTwo()
12831 void PluckTwo :: clear()
12833 delayLine
->clear();
12834 delayLine2
->clear();
12835 combDelay
->clear();
12840 void PluckTwo :: setFrequency(MY_FLOAT frequency
)
12842 lastFrequency
= frequency
;
12843 if ( lastFrequency
<= 0.0 ) {
12844 std::cerr
<< "[chuck](via STK): PluckTwo: setFrequency parameter less than or equal to zero!" << std::endl
;
12845 lastFrequency
= 220.0;
12848 // Delay = length - approximate filter delay.
12849 lastLength
= ( Stk::sampleRate() / lastFrequency
);
12850 MY_FLOAT delay
= (lastLength
/ detuning
) - (MY_FLOAT
) 0.5;
12851 if ( delay
<= 0.0 ) delay
= 0.3;
12852 else if ( delay
> length
) delay
= length
;
12853 delayLine
->setDelay( delay
);
12855 delay
= (lastLength
* detuning
) - (MY_FLOAT
) 0.5;
12856 if ( delay
<= 0.0 ) delay
= 0.3;
12857 else if ( delay
> length
) delay
= length
;
12858 delayLine2
->setDelay( delay
);
12860 loopGain
= baseLoopGain
+ (frequency
* (MY_FLOAT
) 0.000005);
12861 if ( loopGain
> 1.0 ) loopGain
= (MY_FLOAT
) 0.99999;
12864 void PluckTwo :: setDetune(MY_FLOAT detune
)
12867 if ( detuning
<= 0.0 ) {
12868 std::cerr
<< "[chuck](via STK): PluckTwo: setDetune parameter less than or equal to zero!" << std::endl
;
12871 delayLine
->setDelay(( lastLength
/ detuning
) - (MY_FLOAT
) 0.5);
12872 delayLine2
->setDelay( (lastLength
* detuning
) - (MY_FLOAT
) 0.5);
12875 void PluckTwo :: setFreqAndDetune(MY_FLOAT frequency
, MY_FLOAT detune
)
12878 this->setFrequency(frequency
);
12881 void PluckTwo :: setPluckPosition(MY_FLOAT position
)
12883 pluckPosition
= position
;
12884 if ( position
< 0.0 ) {
12885 std::cerr
<< "[chuck](via STK): PluckTwo: setPluckPosition parameter is less than zero!" << std::endl
;
12886 pluckPosition
= 0.0;
12888 else if ( position
> 1.0 ) {
12889 std::cerr
<< "[chuck](via STK): PluckTwo: setPluckPosition parameter is greater than 1.0!" << std::endl
;
12890 pluckPosition
= 1.0;
12894 void PluckTwo :: setBaseLoopGain(MY_FLOAT aGain
)
12896 baseLoopGain
= aGain
;
12897 loopGain
= baseLoopGain
+ (lastFrequency
* (MY_FLOAT
) 0.000005);
12898 if ( loopGain
> 0.99999 ) loopGain
= (MY_FLOAT
) 0.99999;
12901 void PluckTwo :: noteOff(MY_FLOAT amplitude
)
12903 loopGain
= ((MY_FLOAT
) 1.0 - amplitude
) * (MY_FLOAT
) 0.5;
12905 #if defined(_STK_DEBUG_)
12906 std::cerr
<< "[chuck](via STK): PluckTwo: NoteOff amplitude = " << amplitude
<< std::endl
;
12910 /***************************************************/
12912 \brief STK plucked string model class.
12914 This class implements a simple plucked string
12915 physical model based on the Karplus-Strong
12918 This is a digital waveguide model, making its
12919 use possibly subject to patents held by
12920 Stanford University, Yamaha, and others.
12921 There exist at least two patents, assigned to
12922 Stanford, bearing the names of Karplus and/or
12925 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
12927 /***************************************************/
12930 Plucked :: Plucked(MY_FLOAT lowestFrequency
)
12932 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
12933 loopGain
= (MY_FLOAT
) 0.999;
12934 delayLine
= new DelayA( (MY_FLOAT
)(length
/ 2.0), length
);
12935 loopFilter
= new OneZero
;
12936 pickFilter
= new OnePole
;
12941 Plucked :: ~Plucked()
12949 void Plucked :: clear()
12951 delayLine
->clear();
12952 loopFilter
->clear();
12953 pickFilter
->clear();
12956 void Plucked :: setFrequency(MY_FLOAT frequency
)
12958 MY_FLOAT freakency
= frequency
;
12959 if ( frequency
<= 0.0 ) {
12960 std::cerr
<< "[chuck](via STK): Plucked: setFrequency parameter is less than or equal to zero!" << std::endl
;
12964 // Delay = length - approximate filter delay.
12965 MY_FLOAT delay
= (Stk::sampleRate() / freakency
) - (MY_FLOAT
) 0.5;
12966 if (delay
<= 0.0) delay
= 0.3;
12967 else if (delay
> length
) delay
= length
;
12968 delayLine
->setDelay(delay
);
12969 loopGain
= 0.995 + (freakency
* 0.000005);
12970 if ( loopGain
>= 1.0 ) loopGain
= (MY_FLOAT
) 0.99999;
12973 void Plucked :: pluck(MY_FLOAT amplitude
)
12975 MY_FLOAT gain
= amplitude
;
12976 if ( gain
> 1.0 ) {
12977 std::cerr
<< "[chuck](via STK): Plucked: pluck amplitude greater than 1.0!" << std::endl
;
12980 else if ( gain
< 0.0 ) {
12981 std::cerr
<< "[chuck](via STK): Plucked: pluck amplitude less than zero!" << std::endl
;
12985 pickFilter
->setPole((MY_FLOAT
) 0.999 - (gain
* (MY_FLOAT
) 0.15));
12986 pickFilter
->setGain(gain
* (MY_FLOAT
) 0.5);
12987 for (long i
=0; i
<length
; i
++)
12988 // Fill delay with noise additively with current contents.
12989 delayLine
->tick( 0.6 * delayLine
->lastOut() + pickFilter
->tick( noise
->tick() ) );
12992 void Plucked :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
12994 this->setFrequency(frequency
);
12995 this->pluck(amplitude
);
12997 #if defined(_STK_DEBUG_)
12998 std::cerr
<< "[chuck](via STK): Plucked: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
13002 void Plucked :: noteOff(MY_FLOAT amplitude
)
13004 loopGain
= (MY_FLOAT
) 1.0 - amplitude
;
13005 if ( loopGain
< 0.0 ) {
13006 std::cerr
<< "[chuck](via STK): Plucked: noteOff amplitude greater than 1.0!" << std::endl
;
13009 else if ( loopGain
> 1.0 ) {
13010 std::cerr
<< "[chuck](via STK): Plucked: noteOff amplitude less than or zero!" << std::endl
;
13011 loopGain
= (MY_FLOAT
) 0.99999;
13014 #if defined(_STK_DEBUG_)
13015 std::cerr
<< "[chuck](via STK): Plucked: NoteOff amplitude = " << amplitude
<< std::endl
;
13019 MY_FLOAT
Plucked :: tick()
13021 // Here's the whole inner loop of the instrument!!
13022 lastOutput
= delayLine
->tick( loopFilter
->tick( delayLine
->lastOut() * loopGain
) );
13023 lastOutput
*= (MY_FLOAT
) 3.0;
13026 /***************************************************/
13027 /*! \class PoleZero
13028 \brief STK one-pole, one-zero filter class.
13030 This protected Filter subclass implements
13031 a one-pole, one-zero digital filter. A
13032 method is provided for creating an allpass
13033 filter with a given coefficient. Another
13034 method is provided to create a DC blocking filter.
13036 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
13038 /***************************************************/
13041 PoleZero :: PoleZero() : Filter()
13043 // Default setting for pass-through.
13044 MY_FLOAT B
[2] = {1.0, 0.0};
13045 MY_FLOAT A
[2] = {1.0, 0.0};
13046 Filter::setCoefficients( 2, B
, 2, A
);
13049 PoleZero :: ~PoleZero()
13053 void PoleZero :: clear(void)
13058 void PoleZero :: setB0(MY_FLOAT b0
)
13063 void PoleZero :: setB1(MY_FLOAT b1
)
13068 void PoleZero :: setA1(MY_FLOAT a1
)
13073 void PoleZero :: setAllpass(MY_FLOAT coefficient
)
13075 b
[0] = coefficient
;
13077 a
[0] = 1.0; // just in case
13078 a
[1] = coefficient
;
13081 void PoleZero :: setBlockZero(MY_FLOAT thePole
)
13085 a
[0] = 1.0; // just in case
13089 void PoleZero :: setGain(MY_FLOAT theGain
)
13091 Filter::setGain(theGain
);
13094 MY_FLOAT
PoleZero :: getGain(void) const
13096 return Filter::getGain();
13099 MY_FLOAT
PoleZero :: lastOut(void) const
13101 return Filter::lastOut();
13104 MY_FLOAT
PoleZero :: tick(MY_FLOAT sample
)
13106 inputs
[0] = gain
* sample
;
13107 outputs
[0] = b
[0] * inputs
[0] + b
[1] * inputs
[1] - a
[1] * outputs
[1];
13108 inputs
[1] = inputs
[0];
13109 outputs
[1] = outputs
[0];
13114 MY_FLOAT
*PoleZero :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
13116 for (unsigned int i
=0; i
<vectorSize
; i
++)
13117 vector
[i
] = tick(vector
[i
]);
13122 /***************************************************/
13123 /*! \class ReedTabl
13124 \brief STK reed table class.
13126 This class implements a simple one breakpoint,
13127 non-linear reed function, as described by
13128 Smith (1986). This function is based on a
13129 memoryless non-linear spring model of the reed
13130 (the reed mass is ignored) which saturates when
13131 the reed collides with the mouthpiece facing.
13133 See McIntyre, Schumacher, & Woodhouse (1983),
13134 Smith (1986), Hirschman, Cook, Scavone, and
13135 others for more information.
13137 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
13139 /***************************************************/
13142 ReedTabl :: ReedTabl()
13144 offSet
= (MY_FLOAT
) 0.6; // Offset is a bias, related to reed rest position.
13145 slope
= (MY_FLOAT
) -0.8; // Slope corresponds loosely to reed stiffness.
13148 ReedTabl :: ~ReedTabl()
13153 void ReedTabl :: setOffset(MY_FLOAT aValue
)
13158 void ReedTabl :: setSlope(MY_FLOAT aValue
)
13163 MY_FLOAT
ReedTabl :: lastOut() const
13168 MY_FLOAT
ReedTabl :: tick(MY_FLOAT input
)
13170 // The input is differential pressure across the reed.
13171 lastOutput
= offSet
+ (slope
* input
);
13173 // If output is > 1, the reed has slammed shut and the
13174 // reflection function value saturates at 1.0.
13175 if (lastOutput
> 1.0) lastOutput
= (MY_FLOAT
) 1.0;
13177 // This is nearly impossible in a physical system, but
13178 // a reflection function value of -1.0 corresponds to
13179 // an open end (and no discontinuity in bore profile).
13180 if (lastOutput
< -1.0) lastOutput
= (MY_FLOAT
) -1.0;
13184 MY_FLOAT
*ReedTabl :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
13186 for (unsigned int i
=0; i
<vectorSize
; i
++)
13187 vector
[i
] = tick(vector
[i
]);
13192 /***************************************************/
13193 /*! \class Resonate
13194 \brief STK noise driven formant filter.
13196 This instrument contains a noise source, which
13197 excites a biquad resonance filter, with volume
13198 controlled by an ADSR.
13200 Control Change Numbers:
13201 - Resonance Frequency (0-Nyquist) = 2
13203 - Notch Frequency (0-Nyquist) = 11
13205 - Envelope Gain = 128
13207 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
13209 /***************************************************/
13212 Resonate :: Resonate()
13217 filter
= new BiQuad
;
13218 poleFrequency
= 4000.0;
13220 // Set the filter parameters.
13221 filter
->setResonance( poleFrequency
, poleRadius
, TRUE
);
13222 zeroFrequency
= 0.0;
13226 Resonate :: ~Resonate()
13233 void Resonate :: keyOn()
13238 void Resonate :: keyOff()
13243 void Resonate :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
13245 adsr
->setTarget( amplitude
);
13247 this->setResonance(frequency
, poleRadius
);
13249 #if defined(_STK_DEBUG_)
13250 std::cerr
<< "[chuck](via STK): Resonate: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
13253 void Resonate :: noteOff(MY_FLOAT amplitude
)
13257 #if defined(_STK_DEBUG_)
13258 std::cerr
<< "[chuck](via STK): Resonate: NoteOff amplitude = " << amplitude
<< std::endl
;
13262 void Resonate :: setResonance(MY_FLOAT frequency
, MY_FLOAT radius
)
13264 poleFrequency
= frequency
;
13265 if ( frequency
< 0.0 ) {
13266 std::cerr
<< "[chuck](via STK): Resonate: setResonance frequency parameter is less than zero!" << std::endl
;
13267 poleFrequency
= 0.0;
13270 poleRadius
= radius
;
13271 if ( radius
< 0.0 ) {
13272 std::cerr
<< "[chuck](via STK): Resonate: setResonance radius parameter is less than 0.0!" << std::endl
;
13275 else if ( radius
>= 1.0 ) {
13276 std::cerr
<< "[chuck](via STK): Resonate: setResonance radius parameter is greater than or equal to 1.0, which is unstable!" << std::endl
;
13277 poleRadius
= 0.9999;
13279 filter
->setResonance( poleFrequency
, poleRadius
, TRUE
);
13282 void Resonate :: setNotch(MY_FLOAT frequency
, MY_FLOAT radius
)
13284 zeroFrequency
= frequency
;
13285 if ( frequency
< 0.0 ) {
13286 std::cerr
<< "[chuck](via STK): Resonate: setNotch frequency parameter is less than zero!" << std::endl
;
13287 zeroFrequency
= 0.0;
13290 zeroRadius
= radius
;
13291 if ( radius
< 0.0 ) {
13292 std::cerr
<< "[chuck](via STK): Resonate: setNotch radius parameter is less than 0.0!" << std::endl
;
13296 filter
->setNotch( zeroFrequency
, zeroRadius
);
13299 void Resonate :: setEqualGainZeroes()
13301 filter
->setEqualGainZeroes();
13304 MY_FLOAT
Resonate :: tick()
13306 lastOutput
= filter
->tick(noise
->tick());
13307 lastOutput
*= adsr
->tick();
13311 void Resonate :: controlChange(int number
, MY_FLOAT value
)
13313 MY_FLOAT norm
= value
* ONE_OVER_128
;
13316 std::cerr
<< "[chuck](via STK): Resonate: Control value less than zero!" << std::endl
;
13318 else if ( norm
> 1.0 ) {
13320 std::cerr
<< "[chuck](via STK): Resonate: Control value greater than 128.0!" << std::endl
;
13323 if (number
== 2) // 2
13324 setResonance( norm
* Stk::sampleRate() * 0.5, poleRadius
);
13325 else if (number
== 4) // 4
13326 setResonance( poleFrequency
, norm
*0.9999 );
13327 else if (number
== 11) // 11
13328 this->setNotch( norm
* Stk::sampleRate() * 0.5, zeroRadius
);
13329 else if (number
== 1)
13330 this->setNotch( zeroFrequency
, norm
);
13331 else if (number
== __SK_AfterTouch_Cont_
) // 128
13332 adsr
->setTarget( norm
);
13334 std::cerr
<< "[chuck](via STK): Resonate: Undefined Control Number (" << number
<< ")!!" << std::endl
;
13336 #if defined(_STK_DEBUG_)
13337 std::cerr
<< "[chuck](via STK): Resonate: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
13340 /***************************************************/
13342 \brief STK abstract reverberator parent class.
13344 This class provides common functionality for
13345 STK reverberator subclasses.
13347 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
13349 /***************************************************/
13357 Reverb :: ~Reverb()
13361 void Reverb :: setEffectMix(MY_FLOAT mix
)
13366 MY_FLOAT
Reverb :: lastOut() const
13368 return (lastOutput
[0] + lastOutput
[1]) * 0.5;
13371 MY_FLOAT
Reverb :: lastOutLeft() const
13373 return lastOutput
[0];
13376 MY_FLOAT
Reverb :: lastOutRight() const
13378 return lastOutput
[1];
13381 MY_FLOAT
*Reverb :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
13383 for (unsigned int i
=0; i
<vectorSize
; i
++)
13384 vector
[i
] = tick(vector
[i
]);
13389 bool Reverb :: isPrime(int number
)
13391 if (number
== 2) return true;
13393 for (int i
=3; i
<(int)sqrt((double)number
)+1; i
+=2)
13394 if ( (number
% i
) == 0) return false;
13395 return true; /* prime */
13397 else return false; /* even */
13399 /***************************************************/
13401 \brief STK Fender Rhodes-like electric piano FM
13402 synthesis instrument.
13404 This class implements two simple FM Pairs
13405 summed together, also referred to as algorithm
13409 Algorithm 5 is : 4->3--\
13414 Control Change Numbers:
13415 - Modulator Index One = 2
13416 - Crossfade of Outputs = 4
13419 - ADSR 2 & 4 Target = 128
13421 The basic Chowning/Stanford FM patent expired
13422 in 1995, but there exist follow-on patents,
13423 mostly assigned to Yamaha. If you are of the
13424 type who should worry about this (making
13427 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
13429 /***************************************************/
13435 // Concatenate the STK rawwave path to the rawwave files
13436 for ( int i
=0; i
<3; i
++ )
13437 waves
[i
] = new WaveLoop( "special:sinewave", TRUE
);
13438 waves
[3] = new WaveLoop( "special:fwavblnk", TRUE
);
13440 this->setRatio(0, 1.0);
13441 this->setRatio(1, 0.5);
13442 this->setRatio(2, 1.0);
13443 this->setRatio(3, 15.0);
13445 gains
[0] = __FM_gains
[99];
13446 gains
[1] = __FM_gains
[90];
13447 gains
[2] = __FM_gains
[99];
13448 gains
[3] = __FM_gains
[67];
13450 adsr
[0]->setAllTimes( 0.001, 1.50, 0.0, 0.04);
13451 adsr
[1]->setAllTimes( 0.001, 1.50, 0.0, 0.04);
13452 adsr
[2]->setAllTimes( 0.001, 1.00, 0.0, 0.04);
13453 adsr
[3]->setAllTimes( 0.001, 0.25, 0.0, 0.04);
13455 twozero
->setGain((MY_FLOAT
) 1.0);
13458 Rhodey :: ~Rhodey()
13462 void Rhodey :: setFrequency(MY_FLOAT frequency
)
13464 baseFrequency
= frequency
* (MY_FLOAT
) 2.0;
13466 for (int i
=0; i
<nOperators
; i
++ )
13467 waves
[i
]->setFrequency( baseFrequency
* ratios
[i
] );
13470 void Rhodey :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
13472 gains
[0] = amplitude
* __FM_gains
[99];
13473 gains
[1] = amplitude
* __FM_gains
[90];
13474 gains
[2] = amplitude
* __FM_gains
[99];
13475 gains
[3] = amplitude
* __FM_gains
[67];
13476 this->setFrequency(frequency
);
13479 #if defined(_STK_DEBUG_)
13480 cerr
<< "Rhodey: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< endl
;
13484 MY_FLOAT
Rhodey :: tick()
13486 MY_FLOAT temp
, temp2
;
13488 temp
= gains
[1] * adsr
[1]->tick() * waves
[1]->tick();
13489 temp
= temp
* control1
;
13491 waves
[0]->addPhaseOffset(temp
);
13492 waves
[3]->addPhaseOffset(twozero
->lastOut());
13493 temp
= gains
[3] * adsr
[3]->tick() * waves
[3]->tick();
13494 twozero
->tick(temp
);
13496 waves
[2]->addPhaseOffset(temp
);
13497 temp
= ( 1.0 - (control2
* 0.5)) * gains
[0] * adsr
[0]->tick() * waves
[0]->tick();
13498 temp
+= control2
* 0.5 * gains
[2] * adsr
[2]->tick() * waves
[2]->tick();
13500 // Calculate amplitude modulation and apply it to output.
13501 temp2
= vibrato
->tick() * modDepth
;
13502 temp
= temp
* (1.0 + temp2
);
13504 lastOutput
= temp
* 0.5;
13507 /***************************************************/
13509 \brief STK SKINI parsing class
13511 This class parses SKINI formatted text
13512 messages. It can be used to parse individual
13513 messages or it can be passed an entire file.
13514 The file specification is Perry's and his
13515 alone, but it's all text so it shouldn't be to
13516 hard to figure out.
13518 SKINI (Synthesis toolKit Instrument Network
13519 Interface) is like MIDI, but allows for
13520 floating-point control changes, note numbers,
13521 etc. The following example causes a sharp
13522 middle C to be played with a velocity of 111.132:
13524 noteOn 60.01 111.13
13526 See also SKINI.txt.
13528 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
13530 /***************************************************/
13532 #include <string.h>
13533 #include <stdlib.h>
13535 // Constructor for use when parsing SKINI strings (coming over socket
13536 // for example. Use parseThis() method with string pointer.
13541 // Constructor for reading SKINI files ... use nextMessage() method.
13542 SKINI :: SKINI(char *fileName
)
13546 myFile
= fopen(fileName
,"r");
13547 if ((long) myFile
< 0) {
13548 sprintf(msg
, "[chuck](via SKINI): Could not open or find file (%s).", fileName
);
13549 handleError(msg
, StkError::FILE_NOT_FOUND
);
13552 this->nextMessage();
13559 /***************** SOME HANDY ROUTINES *******************/
13562 #define __SK_MAX_FIELDS_ 5
13563 #define __SK_MAX_SIZE_ 32
13565 short ignore(char aChar
)
13567 short ignoreIt
= 0;
13568 if (aChar
== 0) ignoreIt
= 1; // Null String Termination
13569 if (aChar
== '\n') ignoreIt
= 1; // Carraige Return???
13570 if (aChar
== '/') ignoreIt
= 2; // Comment Line
13574 short delimit(char aChar
)
13576 if (aChar
== ' ' || // Space
13577 aChar
== ',' || // Or Comma
13578 aChar
== '\t') // Or Tab
13584 short nextChar(char* aString
)
13588 for (i
=0;i
<__SK_MAX_SIZE_
;i
++) {
13589 if ( aString
[i
] != ' ' && // Space
13590 aString
[i
] != ',' && // Or Comma
13591 aString
[i
] != '\t' ) // Or Tab
13597 int subStrings(char *aString
,
13598 char someStrings
[__SK_MAX_FIELDS_
][__SK_MAX_SIZE_
],
13599 int somePointrs
[__SK_MAX_FIELDS_
],
13600 char *remainderString
)
13602 int notDone
,howMany
,point
,temp
;
13606 temp
= nextChar(aString
);
13607 if (temp
>= __SK_MAX_SIZE_
) {
13609 // printf("Confusion here: Ignoring this line\n");
13610 // printf("%s\n",aString);
13614 somePointrs
[howMany
] = point
;
13617 if (aString
[point
] == '\n') {
13621 someStrings
[howMany
][temp
++] = aString
[point
++];
13622 if (temp
>= __SK_MAX_SIZE_
) {
13626 if (delimit(aString
[point
]) || aString
[point
] == '\n') {
13627 someStrings
[howMany
][temp
] = 0;
13629 if (howMany
< __SK_MAX_FIELDS_
) {
13630 temp
= nextChar(&aString
[point
]);
13632 somePointrs
[howMany
-1] = point
;
13637 somePointrs
[howMany
-1] = point
;
13638 while(aString
[point
] != '\n')
13639 remainderString
[temp
++] = aString
[point
++];
13640 remainderString
[temp
] = aString
[point
];
13645 // printf("Got: %i Strings:\n",howMany);
13646 // for (temp=0;temp<howMany;temp++)
13647 // printf("%s\n",someStrings[temp]);
13652 /**************** THE ENCHILLADA !!!! **********************/
13653 /*** This function parses a single string (if it can) ****/
13654 /*** of SKINI message, setting the appropriate variables ***/
13655 /*************************************************************/
13657 long SKINI :: parseThis(char* aString
)
13661 char someStrings
[__SK_MAX_FIELDS_
][__SK_MAX_SIZE_
];
13662 int somePointrs
[__SK_MAX_FIELDS_
];
13664 temp
= nextChar(aString
);
13665 if ((which
= ignore(aString
[temp
]))) {
13666 if (which
== 2) printf("// CommentLine: %s\n",aString
);
13668 return messageType
;
13671 temp
= subStrings(aString
,someStrings
,somePointrs
,remainderString
);
13675 strcpy(msgTypeString
,someStrings
[aField
]);
13676 while ((which
< __SK_MaxMsgTypes_
) &&
13677 (strcmp(msgTypeString
,
13678 skini_msgs
[which
].messageString
))) {
13681 if (which
>= __SK_MaxMsgTypes_
) {
13683 printf("Couldn't parse this message field: =%s\n %s\n",
13684 msgTypeString
,aString
);
13685 return messageType
;
13688 messageType
= skini_msgs
[which
].type
;
13689 // printf("Message Token = %s type = %i\n", msgTypeString,messageType);
13693 if (someStrings
[aField
][0] == '=') {
13694 deltaTime
= (MY_FLOAT
) atof(&someStrings
[aField
][1]);
13695 deltaTime
= -deltaTime
;
13698 deltaTime
= (MY_FLOAT
) atof(someStrings
[aField
]);
13700 // printf("DeltaTime = %f\n",deltaTime);
13703 channel
= atoi(someStrings
[aField
]);
13704 // printf("Channel = %i\n",channel);
13707 if (skini_msgs
[which
].data2
!= NOPE
) {
13708 if (skini_msgs
[which
].data2
== SK_INT
) {
13709 byteTwoInt
= atoi(someStrings
[aField
]);
13710 byteTwo
= (MY_FLOAT
) byteTwoInt
;
13712 else if (skini_msgs
[which
].data2
== SK_DBL
) {
13713 byteTwo
= (MY_FLOAT
) atof(someStrings
[aField
]);
13714 byteTwoInt
= (long) byteTwo
;
13716 else if (skini_msgs
[which
].data2
== SK_STR
) {
13717 temp
= somePointrs
[aField
-1]; /* Hack Danger Here, Why -1??? */
13719 while (aString
[temp
] != '\n') {
13720 remainderString
[temp2
++] = aString
[temp
++];
13722 remainderString
[temp2
] = 0;
13725 byteTwoInt
= skini_msgs
[which
].data2
;
13726 byteTwo
= (MY_FLOAT
) byteTwoInt
;
13731 if (skini_msgs
[which
].data3
!= NOPE
) {
13732 if (skini_msgs
[which
].data3
== SK_INT
) {
13733 byteThreeInt
= atoi(someStrings
[aField
]);
13734 byteThree
= (MY_FLOAT
) byteThreeInt
;
13736 else if (skini_msgs
[which
].data3
== SK_DBL
) {
13737 byteThree
= (MY_FLOAT
) atof(someStrings
[aField
]);
13738 byteThreeInt
= (long) byteThree
;
13740 else if (skini_msgs
[which
].data3
== SK_STR
) {
13741 temp
= somePointrs
[aField
-1]; /* Hack Danger Here, Why -1??? */
13743 while (aString
[temp
] != '\n') {
13744 remainderString
[temp2
++] = aString
[temp
++];
13746 remainderString
[temp2
] = 0;
13749 byteThreeInt
= skini_msgs
[which
].data3
;
13750 byteThree
= (MY_FLOAT
) byteThreeInt
;
13754 byteThreeInt
= byteTwoInt
;
13755 byteThree
= byteTwo
;
13759 return messageType
;
13762 long SKINI :: nextMessage()
13765 char inputString
[1024];
13770 if (!fgets(inputString
,1024,myFile
)) {
13771 printf("// End of Score. Thanks for using SKINI!!\n");
13773 return messageType
;
13775 else if (parseThis(inputString
) == 0) {
13779 return messageType
;
13782 long SKINI :: getType() const
13784 return messageType
;
13787 long SKINI :: getChannel() const
13792 MY_FLOAT
SKINI :: getDelta() const
13797 MY_FLOAT
SKINI :: getByteTwo() const
13802 long SKINI :: getByteTwoInt() const
13807 MY_FLOAT
SKINI :: getByteThree() const
13812 long SKINI :: getByteThreeInt() const
13814 return byteThreeInt
;
13817 const char* SKINI :: getRemainderString()
13819 return remainderString
;
13822 const char* SKINI :: getMessageTypeString()
13824 return msgTypeString
;
13827 const char* SKINI :: whatsThisType(long type
)
13831 for ( i
=0; i
<__SK_MaxMsgTypes_
; i
++ ) {
13832 if ( type
== skini_msgs
[i
].type
) {
13833 strcat(whatString
, skini_msgs
[i
].messageString
);
13834 strcat(whatString
, ",");
13840 const char* SKINI :: whatsThisController(long contNum
)
13844 for ( i
=0; i
<__SK_MaxMsgTypes_
; i
++) {
13845 if ( skini_msgs
[i
].type
== __SK_ControlChange_
13846 && contNum
== skini_msgs
[i
].data2
) {
13847 strcat(whatString
, skini_msgs
[i
].messageString
);
13848 strcat(whatString
, ",");
13855 /***************************************************/
13857 \brief STK sampling synthesis abstract base class.
13859 This instrument contains up to 5 attack waves,
13860 5 looped waves, and an ADSR envelope.
13862 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
13864 /***************************************************/
13867 Sampler :: Sampler()
13869 // We don't make the waves here yet, because
13870 // we don't know what they will be.
13872 baseFrequency
= 440.0;
13873 filter
= new OnePole
;
13879 Sampler :: ~Sampler()
13885 void Sampler :: keyOn()
13888 attacks
[0]->reset();
13891 void Sampler :: keyOff()
13896 void Sampler :: noteOff(MY_FLOAT amplitude
)
13900 #if defined(_STK_DEBUG_)
13901 cerr
<< "Sampler: NoteOff amplitude = " << amplitude
<< endl
;
13905 MY_FLOAT
Sampler :: tick()
13907 lastOutput
= attackGain
* attacks
[whichOne
]->tick();
13908 lastOutput
+= loopGain
* loops
[whichOne
]->tick();
13909 lastOutput
= filter
->tick(lastOutput
);
13910 lastOutput
*= adsr
->tick();
13913 /***************************************************/
13914 /*! \class Saxofony
13915 \brief STK faux conical bore reed instrument class.
13917 This class implements a "hybrid" digital
13918 waveguide instrument that can generate a
13919 variety of wind-like sounds. It has also been
13920 referred to as the "blowed string" model. The
13921 waveguide section is essentially that of a
13922 string, with one rigid and one lossy
13923 termination. The non-linear function is a
13924 reed table. The string can be "blown" at any
13925 point between the terminations, though just as
13926 with strings, it is impossible to excite the
13927 system at either end. If the excitation is
13928 placed at the string mid-point, the sound is
13929 that of a clarinet. At points closer to the
13930 "bridge", the sound is closer to that of a
13931 saxophone. See Scavone (2002) for more details.
13933 This is a digital waveguide model, making its
13934 use possibly subject to patents held by Stanford
13935 University, Yamaha, and others.
13937 Control Change Numbers:
13938 - Reed Stiffness = 2
13939 - Reed Aperture = 26
13941 - Blow Position = 11
13942 - Vibrato Frequency = 29
13944 - Breath Pressure = 128
13946 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
13948 /***************************************************/
13951 Saxofony :: Saxofony(MY_FLOAT lowestFrequency
)
13953 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
13954 // Initialize blowing position to 0.2 of length / 2.
13956 delays
[0] = (DelayL
*) new DelayL( (1.0-position
) * (length
>> 1), length
);
13957 delays
[1] = (DelayL
*) new DelayL( position
* (length
>> 1), length
);
13959 reedTable
= new ReedTabl
;
13960 reedTable
->setOffset((MY_FLOAT
) 0.7);
13961 reedTable
->setSlope((MY_FLOAT
) 0.3);
13962 filter
= new OneZero
;
13963 envelope
= new Envelope
;
13966 // Concatenate the STK rawwave path to the rawwave file
13967 vibrato
= new WaveLoop( "special:sinewave", TRUE
);
13968 vibrato
->setFrequency((MY_FLOAT
) 5.735);
13970 outputGain
= (MY_FLOAT
) 0.3;
13971 noiseGain
= (MY_FLOAT
) 0.2;
13972 vibratoGain
= (MY_FLOAT
) 0.1;
13975 Saxofony :: ~Saxofony()
13986 void Saxofony :: clear()
13988 delays
[0]->clear();
13989 delays
[1]->clear();
13990 filter
->tick((MY_FLOAT
) 0.0);
13993 void Saxofony :: setFrequency(MY_FLOAT frequency
)
13995 MY_FLOAT freakency
= frequency
;
13996 if ( frequency
<= 0.0 ) {
13997 std::cerr
<< "[chuck](via STK): Saxofony: setFrequency parameter is less than or equal to zero!" << std::endl
;
14001 MY_FLOAT delay
= (Stk::sampleRate() / freakency
) - (MY_FLOAT
) 3.0;
14002 if (delay
<= 0.0) delay
= 0.3;
14003 else if (delay
> length
) delay
= length
;
14005 delays
[0]->setDelay((1.0-position
) * delay
);
14006 delays
[1]->setDelay(position
* delay
);
14009 void Saxofony :: setBlowPosition(MY_FLOAT aPosition
)
14011 if (position
== aPosition
) return;
14013 if (aPosition
< 0.0) position
= 0.0;
14014 else if (aPosition
> 1.0) position
= 1.0;
14015 else position
= aPosition
;
14017 MY_FLOAT total_delay
= delays
[0]->getDelay();
14018 total_delay
+= delays
[1]->getDelay();
14020 delays
[0]->setDelay((1.0-position
) * total_delay
);
14021 delays
[1]->setDelay(position
* total_delay
);
14024 void Saxofony :: startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
14026 envelope
->setRate(rate
);
14027 envelope
->setTarget(amplitude
);
14030 void Saxofony :: stopBlowing(MY_FLOAT rate
)
14032 envelope
->setRate(rate
);
14033 envelope
->setTarget((MY_FLOAT
) 0.0);
14036 void Saxofony :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
14038 setFrequency(frequency
);
14039 startBlowing((MY_FLOAT
) 0.55 + (amplitude
* 0.30), amplitude
* 0.005);
14040 outputGain
= amplitude
+ 0.001;
14042 #if defined(_STK_DEBUG_)
14043 std::cerr
<< "[chuck](via STK): Saxofony: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
14047 void Saxofony :: noteOff(MY_FLOAT amplitude
)
14049 this->stopBlowing(amplitude
* 0.01);
14051 #if defined(_STK_DEBUG_)
14052 std::cerr
<< "[chuck](via STK): Saxofony: NoteOff amplitude = " << amplitude
<< std::endl
;
14056 MY_FLOAT
Saxofony :: tick()
14058 MY_FLOAT pressureDiff
;
14059 MY_FLOAT breathPressure
;
14062 // Calculate the breath pressure (envelope + noise + vibrato)
14063 breathPressure
= envelope
->tick();
14064 breathPressure
+= breathPressure
* noiseGain
* noise
->tick();
14065 breathPressure
+= breathPressure
* vibratoGain
* vibrato
->tick();
14067 temp
= -0.95 * filter
->tick( delays
[0]->lastOut() );
14068 lastOutput
= temp
- delays
[1]->lastOut();
14069 pressureDiff
= breathPressure
- lastOutput
;
14070 delays
[1]->tick(temp
);
14071 delays
[0]->tick(breathPressure
- (pressureDiff
* reedTable
->tick(pressureDiff
)) - temp
);
14073 lastOutput
*= outputGain
;
14077 void Saxofony :: controlChange(int number
, MY_FLOAT value
)
14079 MY_FLOAT norm
= value
* ONE_OVER_128
;
14082 std::cerr
<< "[chuck](via STK): Saxofony: Control value less than zero!" << std::endl
;
14084 else if ( norm
> 1.0 ) {
14086 std::cerr
<< "[chuck](via STK): Saxofony: Control value greater than 128.0!" << std::endl
;
14089 if (number
== __SK_ReedStiffness_
) // 2
14090 reedTable
->setSlope( 0.1 + (0.4 * norm
) );
14091 else if (number
== __SK_NoiseLevel_
) // 4
14092 noiseGain
= ( norm
* 0.4 );
14093 else if (number
== 29) // 29
14094 vibrato
->setFrequency( norm
* 12.0 );
14095 else if (number
== __SK_ModWheel_
) // 1
14096 vibratoGain
= ( norm
* 0.5 );
14097 else if (number
== __SK_AfterTouch_Cont_
) // 128
14098 envelope
->setValue( norm
);
14099 else if (number
== 11) // 11
14100 this->setBlowPosition( norm
);
14101 else if (number
== 26) // reed table offset
14102 reedTable
->setOffset(0.4 + ( norm
* 0.6));
14104 std::cerr
<< "[chuck](via STK): Saxofony: Undefined Control Number (" << number
<< ")!!" << std::endl
;
14106 #if defined(_STK_DEBUG_)
14107 std::cerr
<< "[chuck](via STK): Saxofony: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
14111 /***************************************************/
14113 \brief PhISEM and PhOLIES class.
14115 PhISEM (Physically Informed Stochastic Event
14116 Modeling) is an algorithmic approach for
14117 simulating collisions of multiple independent
14118 sound producing objects. This class is a
14119 meta-model that can simulate a Maraca, Sekere,
14120 Cabasa, Bamboo Wind Chimes, Water Drops,
14121 Tambourine, Sleighbells, and a Guiro.
14123 PhOLIES (Physically-Oriented Library of
14124 Imitated Environmental Sounds) is a similar
14125 approach for the synthesis of environmental
14126 sounds. This class implements simulations of
14127 breaking sticks, crunchy snow (or not), a
14128 wrench, sandpaper, and more.
14130 Control Change Numbers:
14133 - Number Of Objects = 11
14134 - Resonance Frequency = 1
14135 - Shake Energy = 128
14136 - Instrument Selection = 1071
14142 - Bamboo Chimes = 5
14152 - Nickle + Mug = 15
14154 - Quarter + Mug = 17
14158 - Little Rocks = 21
14159 - Tuned Bamboo Chimes = 22
14161 by Perry R. Cook, 1996 - 1999.
14163 /***************************************************/
14165 #include <stdlib.h>
14166 #include <string.h>
14169 int my_random(int max
) // Return Random Int Between 0 and max
14171 int temp
= (int) ((float)max
* rand() / (RAND_MAX
+ 1.0) );
14175 MY_FLOAT
float_random(MY_FLOAT max
) // Return random float between 0.0 and max
14177 MY_FLOAT temp
= (MY_FLOAT
) (max
* rand() / (RAND_MAX
+ 1.0) );
14181 MY_FLOAT
noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0
14183 MY_FLOAT temp
= (MY_FLOAT
) (2.0 * rand() / (RAND_MAX
+ 1.0) );
14189 #define MARA_SOUND_DECAY 0.95
14190 #define MARA_SYSTEM_DECAY 0.999
14191 #define MARA_GAIN 20.0
14192 #define MARA_NUM_BEANS 25
14193 #define MARA_CENTER_FREQ 3200.0
14194 #define MARA_RESON 0.96
14197 #define SEKE_SOUND_DECAY 0.96
14198 #define SEKE_SYSTEM_DECAY 0.999
14199 #define SEKE_GAIN 20.0
14200 #define SEKE_NUM_BEANS 64
14201 #define SEKE_CENTER_FREQ 5500.0
14202 #define SEKE_RESON 0.6
14205 #define SANDPAPR_SOUND_DECAY 0.999
14206 #define SANDPAPR_SYSTEM_DECAY 0.999
14207 #define SANDPAPR_GAIN 0.5
14208 #define SANDPAPR_NUM_GRAINS 128
14209 #define SANDPAPR_CENTER_FREQ 4500.0
14210 #define SANDPAPR_RESON 0.6
14213 #define CABA_SOUND_DECAY 0.96
14214 #define CABA_SYSTEM_DECAY 0.997
14215 #define CABA_GAIN 40.0
14216 #define CABA_NUM_BEADS 512
14217 #define CABA_CENTER_FREQ 3000.0
14218 #define CABA_RESON 0.7
14220 // Bamboo Wind Chimes
14221 #define BAMB_SOUND_DECAY 0.95
14222 #define BAMB_SYSTEM_DECAY 0.9999
14223 #define BAMB_GAIN 2.0
14224 #define BAMB_NUM_TUBES 1.25
14225 #define BAMB_CENTER_FREQ0 2800.0
14226 #define BAMB_CENTER_FREQ1 0.8 * 2800.0
14227 #define BAMB_CENTER_FREQ2 1.2 * 2800.0
14228 #define BAMB_RESON 0.995
14230 // Tuned Bamboo Wind Chimes (Anklung)
14231 #define TBAMB_SOUND_DECAY 0.95
14232 #define TBAMB_SYSTEM_DECAY 0.9999
14233 #define TBAMB_GAIN 1.0
14234 #define TBAMB_NUM_TUBES 1.25
14235 #define TBAMB_CENTER_FREQ0 1046.6
14236 #define TBAMB_CENTER_FREQ1 1174.8
14237 #define TBAMB_CENTER_FREQ2 1397.0
14238 #define TBAMB_CENTER_FREQ3 1568.0
14239 #define TBAMB_CENTER_FREQ4 1760.0
14240 #define TBAMB_CENTER_FREQ5 2093.3
14241 #define TBAMB_CENTER_FREQ6 2350.0
14242 #define TBAMB_RESON 0.996
14245 #define WUTR_SOUND_DECAY 0.95
14246 #define WUTR_SYSTEM_DECAY 0.996
14247 #define WUTR_GAIN 1.0
14248 #define WUTR_NUM_SOURCES 10
14249 #define WUTR_CENTER_FREQ0 450.0
14250 #define WUTR_CENTER_FREQ1 600.0
14251 #define WUTR_CENTER_FREQ2 750.0
14252 #define WUTR_RESON 0.9985
14253 #define WUTR_FREQ_SWEEP 1.0001
14256 #define TAMB_SOUND_DECAY 0.95
14257 #define TAMB_SYSTEM_DECAY 0.9985
14258 #define TAMB_GAIN 5.0
14259 #define TAMB_NUM_TIMBRELS 32
14260 #define TAMB_SHELL_FREQ 2300
14261 #define TAMB_SHELL_GAIN 0.1
14262 #define TAMB_SHELL_RESON 0.96
14263 #define TAMB_CYMB_FREQ1 5600
14264 #define TAMB_CYMB_FREQ2 8100
14265 #define TAMB_CYMB_RESON 0.99
14268 #define SLEI_SOUND_DECAY 0.97
14269 #define SLEI_SYSTEM_DECAY 0.9994
14270 #define SLEI_GAIN 1.0
14271 #define SLEI_NUM_BELLS 32
14272 #define SLEI_CYMB_FREQ0 2500
14273 #define SLEI_CYMB_FREQ1 5300
14274 #define SLEI_CYMB_FREQ2 6500
14275 #define SLEI_CYMB_FREQ3 8300
14276 #define SLEI_CYMB_FREQ4 9800
14277 #define SLEI_CYMB_RESON 0.99
14280 #define GUIR_SOUND_DECAY 0.95
14281 #define GUIR_GAIN 10.0
14282 #define GUIR_NUM_PARTS 128
14283 #define GUIR_GOURD_FREQ 2500.0
14284 #define GUIR_GOURD_RESON 0.97
14285 #define GUIR_GOURD_FREQ2 4000.0
14286 #define GUIR_GOURD_RESON2 0.97
14289 #define WRENCH_SOUND_DECAY 0.95
14290 #define WRENCH_GAIN 5
14291 #define WRENCH_NUM_PARTS 128
14292 #define WRENCH_FREQ 3200.0
14293 #define WRENCH_RESON 0.99
14294 #define WRENCH_FREQ2 8000.0
14295 #define WRENCH_RESON2 0.992
14298 #define COKECAN_SOUND_DECAY 0.97
14299 #define COKECAN_SYSTEM_DECAY 0.999
14300 #define COKECAN_GAIN 0.8
14301 #define COKECAN_NUM_PARTS 48
14302 #define COKECAN_HELMFREQ 370
14303 #define COKECAN_HELM_RES 0.99
14304 #define COKECAN_METLFREQ0 1025
14305 #define COKECAN_METLFREQ1 1424
14306 #define COKECAN_METLFREQ2 2149
14307 #define COKECAN_METLFREQ3 3596
14308 #define COKECAN_METL_RES 0.992
14310 // PhOLIES (Physically-Oriented Library of Imitated Environmental
14311 // Sounds), Perry Cook, 1997-8
14314 #define STIX1_SOUND_DECAY 0.96
14315 #define STIX1_SYSTEM_DECAY 0.998
14316 #define STIX1_GAIN 30.0
14317 #define STIX1_NUM_BEANS 2
14318 #define STIX1_CENTER_FREQ 5500.0
14319 #define STIX1_RESON 0.6
14322 #define CRUNCH1_SOUND_DECAY 0.95
14323 #define CRUNCH1_SYSTEM_DECAY 0.99806
14324 #define CRUNCH1_GAIN 20.0
14325 #define CRUNCH1_NUM_BEADS 7
14326 #define CRUNCH1_CENTER_FREQ 800.0
14327 #define CRUNCH1_RESON 0.95
14330 #define NEXTMUG_SOUND_DECAY 0.97
14331 #define NEXTMUG_SYSTEM_DECAY 0.9995
14332 #define NEXTMUG_GAIN 0.8
14333 #define NEXTMUG_NUM_PARTS 3
14334 #define NEXTMUG_FREQ0 2123
14335 #define NEXTMUG_FREQ1 4518
14336 #define NEXTMUG_FREQ2 8856
14337 #define NEXTMUG_FREQ3 10753
14338 #define NEXTMUG_RES 0.997
14340 #define PENNY_FREQ0 11000
14341 #define PENNY_FREQ1 5200
14342 #define PENNY_FREQ2 3835
14343 #define PENNY_RES 0.999
14345 #define NICKEL_FREQ0 5583
14346 #define NICKEL_FREQ1 9255
14347 #define NICKEL_FREQ2 9805
14348 #define NICKEL_RES 0.9992
14350 #define DIME_FREQ0 4450
14351 #define DIME_FREQ1 4974
14352 #define DIME_FREQ2 9945
14353 #define DIME_RES 0.9993
14355 #define QUARTER_FREQ0 1708
14356 #define QUARTER_FREQ1 8863
14357 #define QUARTER_FREQ2 9045
14358 #define QUARTER_RES 0.9995
14360 #define FRANC_FREQ0 5583
14361 #define FRANC_FREQ1 11010
14362 #define FRANC_FREQ2 1917
14363 #define FRANC_RES 0.9995
14365 #define PESO_FREQ0 7250
14366 #define PESO_FREQ1 8150
14367 #define PESO_FREQ2 10060
14368 #define PESO_RES 0.9996
14371 #define BIGROCKS_SOUND_DECAY 0.98
14372 #define BIGROCKS_SYSTEM_DECAY 0.9965
14373 #define BIGROCKS_GAIN 20.0
14374 #define BIGROCKS_NUM_PARTS 23
14375 #define BIGROCKS_FREQ 6460
14376 #define BIGROCKS_RES 0.932
14379 #define LITLROCKS_SOUND_DECAY 0.98
14380 #define LITLROCKS_SYSTEM_DECAY 0.99586
14381 #define LITLROCKS_GAIN 20.0
14382 #define LITLROCKS_NUM_PARTS 1600
14383 #define LITLROCKS_FREQ 9000
14384 #define LITLROCKS_RES 0.843
14386 // Finally ... the class code!
14389 Shakers :: Shakers()
14398 for ( i
=0; i
<MAX_FREQS
; i
++ ) {
14400 outputs
[i
][0] = 0.0;
14401 outputs
[i
][1] = 0.0;
14402 coeffs
[i
][0] = 0.0;
14403 coeffs
[i
][1] = 0.0;
14405 center_freqs
[i
] = 0.0;
14407 freq_rand
[i
] = 0.0;
14417 ratchetDelta
= 0.0005;
14418 lastRatchetPos
= 0;
14422 finalZCoeffs
[0] = 1.0;
14423 finalZCoeffs
[1] = 0.0;
14424 finalZCoeffs
[2] = 0.0;
14427 this->setupNum(instType
);
14430 Shakers :: ~Shakers()
14434 #define MAX_SHAKE 2000.0
14436 char instrs
[NUM_INSTR
][10] = {
14437 "Maraca", "Cabasa", "Sekere", "Guiro",
14438 "Waterdrp", "Bamboo", "Tambourn", "Sleighbl",
14439 "Stix1", "Crunch1", "Wrench", "SandPapr",
14440 "CokeCan", "NextMug", "PennyMug", "NicklMug",
14441 "DimeMug", "QuartMug", "FrancMug", "PesoMug",
14442 "BigRocks", "LitlRoks", "TBamboo"
14445 int Shakers :: setupName(char* instr
)
14449 for (int i
=0;i
<NUM_INSTR
;i
++) {
14450 if ( !strcmp(instr
,instrs
[i
]) )
14454 #if defined(_STK_DEBUG_)
14455 std::cerr
<< "[chuck](via STK): Shakers: Setting instrument to " << instrs
[which
] << std::endl
;
14458 return this->setupNum(which
);
14461 void Shakers :: setFinalZs(MY_FLOAT z0
, MY_FLOAT z1
, MY_FLOAT z2
) {
14462 finalZCoeffs
[0] = z0
;
14463 finalZCoeffs
[1] = z1
;
14464 finalZCoeffs
[2] = z2
;
14467 void Shakers :: setDecays(MY_FLOAT sndDecay
, MY_FLOAT sysDecay
) {
14468 soundDecay
= sndDecay
;
14469 systemDecay
= sysDecay
;
14472 int Shakers :: setFreqAndReson(int which
, MY_FLOAT freq
, MY_FLOAT reson
) {
14473 if (which
< MAX_FREQS
) {
14474 resons
[which
] = reson
;
14475 center_freqs
[which
] = freq
;
14476 t_center_freqs
[which
] = freq
;
14477 coeffs
[which
][1] = reson
* reson
;
14478 coeffs
[which
][0] = -reson
* 2.0 * cos(freq
* TWO_PI
/ Stk::sampleRate());
14484 int Shakers :: setupNum(int inst
)
14489 inst
%= 23; // chuck hack
14490 if (inst
== 1) { // Cabasa
14492 nObjects
= CABA_NUM_BEADS
;
14493 defObjs
[inst
] = CABA_NUM_BEADS
;
14494 setDecays(CABA_SOUND_DECAY
, CABA_SYSTEM_DECAY
);
14495 defDecays
[inst
] = CABA_SYSTEM_DECAY
;
14496 decayScale
[inst
] = 0.97;
14498 baseGain
= CABA_GAIN
;
14499 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14502 setFreqAndReson(0,CABA_CENTER_FREQ
,CABA_RESON
);
14503 setFinalZs(1.0,-1.0,0.0);
14505 else if (inst
== 2) { // Sekere
14507 nObjects
= SEKE_NUM_BEANS
;
14508 defObjs
[inst
] = SEKE_NUM_BEANS
;
14509 this->setDecays(SEKE_SOUND_DECAY
,SEKE_SYSTEM_DECAY
);
14510 defDecays
[inst
] = SEKE_SYSTEM_DECAY
;
14511 decayScale
[inst
] = 0.94;
14513 baseGain
= SEKE_GAIN
;
14514 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14517 this->setFreqAndReson(0,SEKE_CENTER_FREQ
,SEKE_RESON
);
14518 this->setFinalZs(1.0, 0.0, -1.0);
14520 else if (inst
== 3) { // Guiro
14522 nObjects
= GUIR_NUM_PARTS
;
14523 defObjs
[inst
] = GUIR_NUM_PARTS
;
14524 setDecays(GUIR_SOUND_DECAY
,1.0);
14525 defDecays
[inst
] = 0.9999;
14526 decayScale
[inst
] = 1.0;
14528 baseGain
= GUIR_GAIN
;
14529 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14534 freq_rand
[0] = 0.0;
14535 freq_rand
[1] = 0.0;
14536 setFreqAndReson(0,GUIR_GOURD_FREQ
,GUIR_GOURD_RESON
);
14537 setFreqAndReson(1,GUIR_GOURD_FREQ2
,GUIR_GOURD_RESON2
);
14541 else if (inst
== 4) { // Water Drops
14543 nObjects
= WUTR_NUM_SOURCES
;
14544 defObjs
[inst
] = WUTR_NUM_SOURCES
;
14545 setDecays(WUTR_SOUND_DECAY
,WUTR_SYSTEM_DECAY
);
14546 defDecays
[inst
] = WUTR_SYSTEM_DECAY
;
14547 decayScale
[inst
] = 0.8;
14549 baseGain
= WUTR_GAIN
;
14550 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14557 freq_rand
[0] = 0.2;
14558 freq_rand
[1] = 0.2;
14559 freq_rand
[2] = 0.2;
14560 setFreqAndReson(0,WUTR_CENTER_FREQ0
,WUTR_RESON
);
14561 setFreqAndReson(1,WUTR_CENTER_FREQ0
,WUTR_RESON
);
14562 setFreqAndReson(2,WUTR_CENTER_FREQ0
,WUTR_RESON
);
14563 setFinalZs(1.0,0.0,0.0);
14565 else if (inst
== 5) { // Bamboo
14567 nObjects
= BAMB_NUM_TUBES
;
14568 defObjs
[inst
] = BAMB_NUM_TUBES
;
14569 setDecays(BAMB_SOUND_DECAY
, BAMB_SYSTEM_DECAY
);
14570 defDecays
[inst
] = BAMB_SYSTEM_DECAY
;
14571 decayScale
[inst
] = 0.7;
14573 baseGain
= BAMB_GAIN
;
14574 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14581 freq_rand
[0] = 0.2;
14582 freq_rand
[1] = 0.2;
14583 freq_rand
[2] = 0.2;
14584 setFreqAndReson(0,BAMB_CENTER_FREQ0
,BAMB_RESON
);
14585 setFreqAndReson(1,BAMB_CENTER_FREQ1
,BAMB_RESON
);
14586 setFreqAndReson(2,BAMB_CENTER_FREQ2
,BAMB_RESON
);
14587 setFinalZs(1.0,0.0,0.0);
14589 else if (inst
== 6) { // Tambourine
14591 nObjects
= TAMB_NUM_TIMBRELS
;
14592 defObjs
[inst
] = TAMB_NUM_TIMBRELS
;
14593 setDecays(TAMB_SOUND_DECAY
,TAMB_SYSTEM_DECAY
);
14594 defDecays
[inst
] = TAMB_SYSTEM_DECAY
;
14595 decayScale
[inst
] = 0.95;
14597 baseGain
= TAMB_GAIN
;
14598 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14599 gains
[0]=temp
*TAMB_SHELL_GAIN
;
14605 freq_rand
[0] = 0.0;
14606 freq_rand
[1] = 0.05;
14607 freq_rand
[2] = 0.05;
14608 setFreqAndReson(0,TAMB_SHELL_FREQ
,TAMB_SHELL_RESON
);
14609 setFreqAndReson(1,TAMB_CYMB_FREQ1
,TAMB_CYMB_RESON
);
14610 setFreqAndReson(2,TAMB_CYMB_FREQ2
,TAMB_CYMB_RESON
);
14611 setFinalZs(1.0,0.0,-1.0);
14613 else if (inst
== 7) { // Sleighbell
14615 nObjects
= SLEI_NUM_BELLS
;
14616 defObjs
[inst
] = SLEI_NUM_BELLS
;
14617 setDecays(SLEI_SOUND_DECAY
,SLEI_SYSTEM_DECAY
);
14618 defDecays
[inst
] = SLEI_SYSTEM_DECAY
;
14619 decayScale
[inst
] = 0.9;
14621 baseGain
= SLEI_GAIN
;
14622 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14628 for (i
=0;i
<nFreqs
;i
++) {
14630 freq_rand
[i
] = 0.03;
14632 setFreqAndReson(0,SLEI_CYMB_FREQ0
,SLEI_CYMB_RESON
);
14633 setFreqAndReson(1,SLEI_CYMB_FREQ1
,SLEI_CYMB_RESON
);
14634 setFreqAndReson(2,SLEI_CYMB_FREQ2
,SLEI_CYMB_RESON
);
14635 setFreqAndReson(3,SLEI_CYMB_FREQ3
,SLEI_CYMB_RESON
);
14636 setFreqAndReson(4,SLEI_CYMB_FREQ4
,SLEI_CYMB_RESON
);
14637 setFinalZs(1.0,0.0,-1.0);
14639 else if (inst
== 8) { // Stix1
14641 nObjects
= STIX1_NUM_BEANS
;
14642 defObjs
[inst
] = STIX1_NUM_BEANS
;
14643 setDecays(STIX1_SOUND_DECAY
,STIX1_SYSTEM_DECAY
);
14644 defDecays
[inst
] = STIX1_SYSTEM_DECAY
;
14646 decayScale
[inst
] = 0.96;
14648 baseGain
= STIX1_GAIN
;
14649 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14652 setFreqAndReson(0,STIX1_CENTER_FREQ
,STIX1_RESON
);
14653 setFinalZs(1.0,0.0,-1.0);
14655 else if (inst
== 9) { // Crunch1
14657 nObjects
= CRUNCH1_NUM_BEADS
;
14658 defObjs
[inst
] = CRUNCH1_NUM_BEADS
;
14659 setDecays(CRUNCH1_SOUND_DECAY
,CRUNCH1_SYSTEM_DECAY
);
14660 defDecays
[inst
] = CRUNCH1_SYSTEM_DECAY
;
14661 decayScale
[inst
] = 0.96;
14663 baseGain
= CRUNCH1_GAIN
;
14664 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14667 setFreqAndReson(0,CRUNCH1_CENTER_FREQ
,CRUNCH1_RESON
);
14668 setFinalZs(1.0,-1.0,0.0);
14670 else if (inst
== 10) { // Wrench
14672 nObjects
= WRENCH_NUM_PARTS
;
14673 defObjs
[inst
] = WRENCH_NUM_PARTS
;
14674 setDecays(WRENCH_SOUND_DECAY
,1.0);
14675 defDecays
[inst
] = 0.9999;
14676 decayScale
[inst
] = 0.98;
14678 baseGain
= WRENCH_GAIN
;
14679 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14684 freq_rand
[0] = 0.0;
14685 freq_rand
[1] = 0.0;
14686 setFreqAndReson(0,WRENCH_FREQ
,WRENCH_RESON
);
14687 setFreqAndReson(1,WRENCH_FREQ2
,WRENCH_RESON2
);
14691 else if (inst
== 11) { // Sandpapr
14693 nObjects
= SANDPAPR_NUM_GRAINS
;
14694 defObjs
[inst
] = SANDPAPR_NUM_GRAINS
;
14695 this->setDecays(SANDPAPR_SOUND_DECAY
,SANDPAPR_SYSTEM_DECAY
);
14696 defDecays
[inst
] = SANDPAPR_SYSTEM_DECAY
;
14697 decayScale
[inst
] = 0.97;
14699 baseGain
= SANDPAPR_GAIN
;
14700 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14703 this->setFreqAndReson(0,SANDPAPR_CENTER_FREQ
,SANDPAPR_RESON
);
14704 this->setFinalZs(1.0, 0.0, -1.0);
14706 else if (inst
== 12) { // Cokecan
14708 nObjects
= COKECAN_NUM_PARTS
;
14709 defObjs
[inst
] = COKECAN_NUM_PARTS
;
14710 setDecays(COKECAN_SOUND_DECAY
,COKECAN_SYSTEM_DECAY
);
14711 defDecays
[inst
] = COKECAN_SYSTEM_DECAY
;
14712 decayScale
[inst
] = 0.95;
14714 baseGain
= COKECAN_GAIN
;
14715 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14726 setFreqAndReson(0,COKECAN_HELMFREQ
,COKECAN_HELM_RES
);
14727 setFreqAndReson(1,COKECAN_METLFREQ0
,COKECAN_METL_RES
);
14728 setFreqAndReson(2,COKECAN_METLFREQ1
,COKECAN_METL_RES
);
14729 setFreqAndReson(3,COKECAN_METLFREQ2
,COKECAN_METL_RES
);
14730 setFreqAndReson(4,COKECAN_METLFREQ3
,COKECAN_METL_RES
);
14731 setFinalZs(1.0,0.0,-1.0);
14733 else if (inst
>12 && inst
<20) { // Nextmug
14735 nObjects
= NEXTMUG_NUM_PARTS
;
14736 defObjs
[inst
] = NEXTMUG_NUM_PARTS
;
14737 setDecays(NEXTMUG_SOUND_DECAY
,NEXTMUG_SYSTEM_DECAY
);
14738 defDecays
[inst
] = NEXTMUG_SYSTEM_DECAY
;
14739 decayScale
[inst
] = 0.95;
14741 baseGain
= NEXTMUG_GAIN
;
14742 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14753 setFreqAndReson(0,NEXTMUG_FREQ0
,NEXTMUG_RES
);
14754 setFreqAndReson(1,NEXTMUG_FREQ1
,NEXTMUG_RES
);
14755 setFreqAndReson(2,NEXTMUG_FREQ2
,NEXTMUG_RES
);
14756 setFreqAndReson(3,NEXTMUG_FREQ3
,NEXTMUG_RES
);
14757 setFinalZs(1.0,0.0,-1.0);
14759 if (inst
== 14) { // Mug + Penny
14762 gains
[5] = temp
*0.8;
14763 gains
[6] = temp
*0.5;
14764 setFreqAndReson(4,PENNY_FREQ0
,PENNY_RES
);
14765 setFreqAndReson(5,PENNY_FREQ1
,PENNY_RES
);
14766 setFreqAndReson(6,PENNY_FREQ2
,PENNY_RES
);
14768 else if (inst
== 15) { // Mug + Nickel
14771 gains
[5] = temp
*0.8;
14772 gains
[6] = temp
*0.5;
14773 setFreqAndReson(4,NICKEL_FREQ0
,NICKEL_RES
);
14774 setFreqAndReson(5,NICKEL_FREQ1
,NICKEL_RES
);
14775 setFreqAndReson(6,NICKEL_FREQ2
,NICKEL_RES
);
14777 else if (inst
== 16) { // Mug + Dime
14780 gains
[5] = temp
*0.8;
14781 gains
[6] = temp
*0.5;
14782 setFreqAndReson(4,DIME_FREQ0
,DIME_RES
);
14783 setFreqAndReson(5,DIME_FREQ1
,DIME_RES
);
14784 setFreqAndReson(6,DIME_FREQ2
,DIME_RES
);
14786 else if (inst
== 17) { // Mug + Quarter
14788 gains
[4] = temp
*1.3;
14789 gains
[5] = temp
*1.0;
14790 gains
[6] = temp
*0.8;
14791 setFreqAndReson(4,QUARTER_FREQ0
,QUARTER_RES
);
14792 setFreqAndReson(5,QUARTER_FREQ1
,QUARTER_RES
);
14793 setFreqAndReson(6,QUARTER_FREQ2
,QUARTER_RES
);
14795 else if (inst
== 18) { // Mug + Franc
14797 gains
[4] = temp
*0.7;
14798 gains
[5] = temp
*0.4;
14799 gains
[6] = temp
*0.3;
14800 setFreqAndReson(4,FRANC_FREQ0
,FRANC_RES
);
14801 setFreqAndReson(5,FRANC_FREQ1
,FRANC_RES
);
14802 setFreqAndReson(6,FRANC_FREQ2
,FRANC_RES
);
14804 else if (inst
== 19) { // Mug + Peso
14807 gains
[5] = temp
*1.2;
14808 gains
[6] = temp
*0.7;
14809 setFreqAndReson(4,PESO_FREQ0
,PESO_RES
);
14810 setFreqAndReson(5,PESO_FREQ1
,PESO_RES
);
14811 setFreqAndReson(6,PESO_FREQ2
,PESO_RES
);
14814 else if (inst
== 20) { // Big Rocks
14817 nObjects
= BIGROCKS_NUM_PARTS
;
14818 defObjs
[inst
] = BIGROCKS_NUM_PARTS
;
14819 setDecays(BIGROCKS_SOUND_DECAY
,BIGROCKS_SYSTEM_DECAY
);
14820 defDecays
[inst
] = BIGROCKS_SYSTEM_DECAY
;
14821 decayScale
[inst
] = 0.95;
14822 baseGain
= BIGROCKS_GAIN
;
14823 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14826 freq_rand
[0] = 0.11;
14827 setFreqAndReson(0,BIGROCKS_FREQ
,BIGROCKS_RES
);
14828 setFinalZs(1.0,0.0,-1.0);
14830 else if (inst
== 21) { // Little Rocks
14833 nObjects
= LITLROCKS_NUM_PARTS
;
14834 defObjs
[inst
] = LITLROCKS_NUM_PARTS
;
14835 setDecays(LITLROCKS_SOUND_DECAY
,LITLROCKS_SYSTEM_DECAY
);
14836 defDecays
[inst
] = LITLROCKS_SYSTEM_DECAY
;
14837 decayScale
[inst
] = 0.95;
14838 baseGain
= LITLROCKS_GAIN
;
14839 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14842 freq_rand
[0] = 0.18;
14843 setFreqAndReson(0,LITLROCKS_FREQ
,LITLROCKS_RES
);
14844 setFinalZs(1.0,0.0,-1.0);
14846 else if (inst
== 22) { // Tuned Bamboo
14848 nObjects
= TBAMB_NUM_TUBES
;
14849 defObjs
[inst
] = TBAMB_NUM_TUBES
;
14850 setDecays(TBAMB_SOUND_DECAY
, TBAMB_SYSTEM_DECAY
);
14851 defDecays
[inst
] = TBAMB_SYSTEM_DECAY
;
14852 decayScale
[inst
] = 0.7;
14854 baseGain
= TBAMB_GAIN
;
14855 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14870 freq_rand
[0] = 0.0;
14871 freq_rand
[1] = 0.0;
14872 freq_rand
[2] = 0.0;
14873 freq_rand
[3] = 0.0;
14874 freq_rand
[4] = 0.0;
14875 freq_rand
[5] = 0.0;
14876 freq_rand
[6] = 0.0;
14877 setFreqAndReson(0,TBAMB_CENTER_FREQ0
,TBAMB_RESON
);
14878 setFreqAndReson(1,TBAMB_CENTER_FREQ1
,TBAMB_RESON
);
14879 setFreqAndReson(2,TBAMB_CENTER_FREQ2
,TBAMB_RESON
);
14880 setFreqAndReson(3,TBAMB_CENTER_FREQ3
,TBAMB_RESON
);
14881 setFreqAndReson(4,TBAMB_CENTER_FREQ4
,TBAMB_RESON
);
14882 setFreqAndReson(5,TBAMB_CENTER_FREQ5
,TBAMB_RESON
);
14883 setFreqAndReson(6,TBAMB_CENTER_FREQ6
,TBAMB_RESON
);
14884 setFinalZs(1.0,0.0,-1.0);
14886 else { // Maraca (inst == 0) or default
14888 nObjects
= MARA_NUM_BEANS
;
14889 defObjs
[0] = MARA_NUM_BEANS
;
14890 setDecays(MARA_SOUND_DECAY
,MARA_SYSTEM_DECAY
);
14891 defDecays
[0] = MARA_SYSTEM_DECAY
;
14892 decayScale
[inst
] = 0.9;
14894 baseGain
= MARA_GAIN
;
14895 temp
= log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
14898 setFreqAndReson(0,MARA_CENTER_FREQ
,MARA_RESON
);
14899 setFinalZs(1.0,-1.0,0.0);
14901 m_noteNum
= inst
; // chuck data
14907 void Shakers :: ck_noteOn(MY_FLOAT amplitude
) {
14908 if (instType
!= m_noteNum
) instType
= this->setupNum(m_noteNum
);
14909 shakeEnergy
+= amplitude
* MAX_SHAKE
* 0.1;
14910 if (shakeEnergy
> MAX_SHAKE
) shakeEnergy
= MAX_SHAKE
;
14911 if (instType
==10 || instType
==3) ratchetPos
+= 1;
14914 void Shakers :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
14916 // Yep ... pretty kludgey, but it works!
14917 int noteNum
= (int) ((12*log(frequency
/220.0)/log(2.0)) + 57.01) % 32;
14918 m_noteNum
= noteNum
;
14919 if (instType
!= noteNum
) instType
= this->setupNum(noteNum
);
14920 shakeEnergy
+= amplitude
* MAX_SHAKE
* 0.1;
14921 if (shakeEnergy
> MAX_SHAKE
) shakeEnergy
= MAX_SHAKE
;
14922 if (instType
==10 || instType
==3) ratchetPos
+= 1;
14924 #if defined(_STK_DEBUG_)
14925 std::cerr
<< "[chuck](via STK): Shakers: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
14929 void Shakers :: noteOff(MY_FLOAT amplitude
)
14932 if (instType
==10 || instType
==3) ratchetPos
= 0;
14935 #define MIN_ENERGY 0.3
14937 MY_FLOAT
Shakers :: tick()
14940 MY_FLOAT temp_rand
;
14943 if (instType
== 4) {
14944 if (shakeEnergy
> MIN_ENERGY
) {
14945 lastOutput
= wuter_tick();
14946 lastOutput
*= 0.0001;
14952 else if (instType
== 22) {
14953 lastOutput
= tbamb_tick();
14955 else if (instType
== 10 || instType
== 3) {
14956 if (ratchetPos
> 0) {
14957 ratchet
-= (ratchetDelta
+ (0.002*totalEnergy
));
14958 if (ratchet
< 0.0) {
14962 totalEnergy
= ratchet
;
14963 lastOutput
= ratchet_tick();
14964 lastOutput
*= 0.0001;
14966 else lastOutput
= 0.0;
14969 // MY_FLOAT generic_tick() {
14970 if (shakeEnergy
> MIN_ENERGY
) {
14971 shakeEnergy
*= systemDecay
; // Exponential system decay
14972 if (float_random(1024.0) < nObjects
) {
14973 sndLevel
+= shakeEnergy
;
14974 for (i
=0;i
<nFreqs
;i
++) {
14975 if (freqalloc
[i
]) {
14976 temp_rand
= t_center_freqs
[i
] * (1.0 + (freq_rand
[i
] * noise_tick()));
14977 coeffs
[i
][0] = -resons
[i
] * 2.0 * cos(temp_rand
* TWO_PI
/ Stk::sampleRate());
14981 inputs
[0] = sndLevel
* noise_tick(); // Actual Sound is Random
14982 for (i
=1; i
<nFreqs
; i
++) {
14983 inputs
[i
] = inputs
[0];
14985 sndLevel
*= soundDecay
; // Exponential Sound decay
14986 finalZ
[2] = finalZ
[1];
14987 finalZ
[1] = finalZ
[0];
14989 for (i
=0;i
<nFreqs
;i
++) {
14990 inputs
[i
] -= outputs
[i
][0]*coeffs
[i
][0]; // Do
14991 inputs
[i
] -= outputs
[i
][1]*coeffs
[i
][1]; // resonant
14992 outputs
[i
][1] = outputs
[i
][0]; // filter
14993 outputs
[i
][0] = inputs
[i
]; // calculations
14994 finalZ
[0] += gains
[i
] * outputs
[i
][1];
14996 data
= finalZCoeffs
[0] * finalZ
[0]; // Extra zero(s) for shape
14997 data
+= finalZCoeffs
[1] * finalZ
[1]; // Extra zero(s) for shape
14998 data
+= finalZCoeffs
[2] * finalZ
[2]; // Extra zero(s) for shape
14999 if (data
> 10000.0) data
= 10000.0;
15000 if (data
< -10000.0) data
= -10000.0;
15001 lastOutput
= data
* 0.0001;
15003 else lastOutput
= 0.0;
15009 void Shakers :: controlChange(int number
, MY_FLOAT value
)
15011 MY_FLOAT norm
= value
* ONE_OVER_128
;
15014 std::cerr
<< "[chuck](via STK): Shakers: Control value less than zero!" << std::endl
;
15016 else if ( norm
> 1.0 ) {
15018 std::cerr
<< "[chuck](via STK): Shakers: Control value greater than 128.0!" << std::endl
;
15024 if (number
== __SK_Breath_
) { // 2 ... energy
15025 shakeEnergy
+= norm
* MAX_SHAKE
* 0.1;
15026 if (shakeEnergy
> MAX_SHAKE
) shakeEnergy
= MAX_SHAKE
;
15027 if (instType
==10 || instType
==3) {
15028 ratchetPos
= (int) fabs(value
- lastRatchetPos
);
15029 ratchetDelta
= 0.0002 * ratchetPos
;
15030 lastRatchetPos
= (int) value
;
15033 else if (number
== __SK_ModFrequency_
) { // 4 ... decay
15034 if (instType
!= 3 && instType
!= 10) {
15035 systemDecay
= defDecays
[instType
] + ((value
- 64.0) *
15036 decayScale
[instType
] *
15037 (1.0 - defDecays
[instType
]) / 64.0 );
15038 gains
[0] = log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
15039 for (i
=1;i
<nFreqs
;i
++) gains
[i
] = gains
[0];
15040 if (instType
== 6) { // tambourine
15041 gains
[0] *= TAMB_SHELL_GAIN
;
15044 else if (instType
== 7) { // sleighbell
15048 else if (instType
== 12) { // cokecan
15049 for (i
=1;i
<nFreqs
;i
++) gains
[i
] *= 1.8;
15051 for (i
=0;i
<nFreqs
;i
++) gains
[i
] *= ((128-value
)/100.0 + 0.36);
15054 else if (number
== __SK_FootControl_
) { // 11 ... number of objects
15055 if (instType
== 5) // bamboo
15056 nObjects
= (MY_FLOAT
) (value
* defObjs
[instType
] / 64.0) + 0.3;
15058 nObjects
= (MY_FLOAT
) (value
* defObjs
[instType
] / 64.0) + 1.1;
15059 gains
[0] = log(nObjects
) * baseGain
/ (MY_FLOAT
) nObjects
;
15060 for (i
=1;i
<nFreqs
;i
++) gains
[i
] = gains
[0];
15061 if (instType
== 6) { // tambourine
15062 gains
[0] *= TAMB_SHELL_GAIN
;
15065 else if (instType
== 7) { // sleighbell
15069 else if (instType
== 12) { // cokecan
15070 for (i
=1;i
<nFreqs
;i
++) gains
[i
] *= 1.8;
15072 if (instType
!= 3 && instType
!= 10) {
15073 // reverse calculate decay setting
15074 double temp
= (double) (64.0 * (systemDecay
-defDecays
[instType
])/(decayScale
[instType
]*(1-defDecays
[instType
])) + 64.0);
15075 // scale gains by decay setting
15076 for (i
=0;i
<nFreqs
;i
++) gains
[i
] *= ((128-temp
)/100.0 + 0.36);
15079 else if (number
== __SK_ModWheel_
) { // 1 ... resonance frequency
15080 for (i
=0; i
<nFreqs
; i
++) {
15081 if (instType
== 6 || instType
== 2 || instType
== 7) // limit range a bit for tambourine
15082 temp
= center_freqs
[i
] * pow (1.008,value
-64);
15084 temp
= center_freqs
[i
] * pow (1.015,value
-64);
15085 t_center_freqs
[i
] = temp
;
15087 coeffs
[i
][0] = -resons
[i
] * 2.0 * cos(temp
* TWO_PI
/ Stk::sampleRate());
15088 coeffs
[i
][1] = resons
[i
]*resons
[i
];
15091 else if (number
== __SK_AfterTouch_Cont_
) { // 128
15092 shakeEnergy
+= norm
* MAX_SHAKE
* 0.1;
15093 if (shakeEnergy
> MAX_SHAKE
) shakeEnergy
= MAX_SHAKE
;
15094 if (instType
==10 || instType
==3) {
15095 ratchetPos
= (int) fabs(value
- lastRatchetPos
);
15096 ratchetDelta
= 0.0002 * ratchetPos
;
15097 lastRatchetPos
= (int) value
;
15100 else if (number
== __SK_ShakerInst_
) { // 1071
15101 instType
= (int) (value
+ 0.5); // Just to be safe
15102 this->setupNum(instType
);
15105 std::cerr
<< "[chuck](via STK): Shakers: Undefined Control Number (" << number
<< ")!!" << std::endl
;
15107 #if defined(_STK_DEBUG_)
15108 std::cerr
<< "[chuck](via STK): Shakers: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
15112 // KLUDGE-O-MATIC-O-RAMA
15114 MY_FLOAT
Shakers :: wuter_tick() {
15117 shakeEnergy
*= systemDecay
; // Exponential system decay
15118 if (my_random(32767) < nObjects
) {
15119 sndLevel
= shakeEnergy
;
15122 center_freqs
[0] = WUTR_CENTER_FREQ1
* (0.75 + (0.25 * noise_tick()));
15123 gains
[0] = fabs(noise_tick());
15126 center_freqs
[1] = WUTR_CENTER_FREQ1
* (1.0 + (0.25 * noise_tick()));
15127 gains
[1] = fabs(noise_tick());
15130 center_freqs
[2] = WUTR_CENTER_FREQ1
* (1.25 + (0.25 * noise_tick()));
15131 gains
[2] = fabs(noise_tick());
15135 gains
[0] *= resons
[0];
15136 if (gains
[0] > 0.001) {
15137 center_freqs
[0] *= WUTR_FREQ_SWEEP
;
15138 coeffs
[0][0] = -resons
[0] * 2.0 *
15139 cos(center_freqs
[0] * TWO_PI
/ Stk::sampleRate());
15141 gains
[1] *= resons
[1];
15142 if (gains
[1] > 0.001) {
15143 center_freqs
[1] *= WUTR_FREQ_SWEEP
;
15144 coeffs
[1][0] = -resons
[1] * 2.0 *
15145 cos(center_freqs
[1] * TWO_PI
/ Stk::sampleRate());
15147 gains
[2] *= resons
[2];
15148 if (gains
[2] > 0.001) {
15149 center_freqs
[2] *= WUTR_FREQ_SWEEP
;
15150 coeffs
[2][0] = -resons
[2] * 2.0 *
15151 cos(center_freqs
[2] * TWO_PI
/ Stk::sampleRate());
15154 sndLevel
*= soundDecay
; // Each (all) event(s)
15155 // decay(s) exponentially
15156 inputs
[0] = sndLevel
;
15157 inputs
[0] *= noise_tick(); // Actual Sound is Random
15158 inputs
[1] = inputs
[0] * gains
[1];
15159 inputs
[2] = inputs
[0] * gains
[2];
15160 inputs
[0] *= gains
[0];
15161 inputs
[0] -= outputs
[0][0]*coeffs
[0][0];
15162 inputs
[0] -= outputs
[0][1]*coeffs
[0][1];
15163 outputs
[0][1] = outputs
[0][0];
15164 outputs
[0][0] = inputs
[0];
15165 data
= gains
[0]*outputs
[0][0];
15166 inputs
[1] -= outputs
[1][0]*coeffs
[1][0];
15167 inputs
[1] -= outputs
[1][1]*coeffs
[1][1];
15168 outputs
[1][1] = outputs
[1][0];
15169 outputs
[1][0] = inputs
[1];
15170 data
+= gains
[1]*outputs
[1][0];
15171 inputs
[2] -= outputs
[2][0]*coeffs
[2][0];
15172 inputs
[2] -= outputs
[2][1]*coeffs
[2][1];
15173 outputs
[2][1] = outputs
[2][0];
15174 outputs
[2][0] = inputs
[2];
15175 data
+= gains
[2]*outputs
[2][0];
15177 finalZ
[2] = finalZ
[1];
15178 finalZ
[1] = finalZ
[0];
15179 finalZ
[0] = data
* 4;
15181 data
= finalZ
[2] - finalZ
[0];
15185 MY_FLOAT
Shakers :: ratchet_tick() {
15187 if (my_random(1024) < nObjects
) {
15188 sndLevel
+= 512 * ratchet
* totalEnergy
;
15190 inputs
[0] = sndLevel
;
15191 inputs
[0] *= noise_tick() * ratchet
;
15192 sndLevel
*= soundDecay
;
15194 inputs
[1] = inputs
[0];
15195 inputs
[0] -= outputs
[0][0]*coeffs
[0][0];
15196 inputs
[0] -= outputs
[0][1]*coeffs
[0][1];
15197 outputs
[0][1] = outputs
[0][0];
15198 outputs
[0][0] = inputs
[0];
15199 inputs
[1] -= outputs
[1][0]*coeffs
[1][0];
15200 inputs
[1] -= outputs
[1][1]*coeffs
[1][1];
15201 outputs
[1][1] = outputs
[1][0];
15202 outputs
[1][0] = inputs
[1];
15204 finalZ
[2] = finalZ
[1];
15205 finalZ
[1] = finalZ
[0];
15206 finalZ
[0] = gains
[0]*outputs
[0][1] + gains
[1]*outputs
[1][1];
15207 data
= finalZ
[0] - finalZ
[2];
15211 MY_FLOAT
Shakers :: tbamb_tick() {
15212 MY_FLOAT data
, temp
;
15213 static int which
= 0;
15216 if (shakeEnergy
> MIN_ENERGY
) {
15217 shakeEnergy
*= systemDecay
; // Exponential system decay
15218 if (float_random(1024.0) < nObjects
) {
15219 sndLevel
+= shakeEnergy
;
15220 which
= my_random(7);
15222 temp
= sndLevel
* noise_tick(); // Actual Sound is Random
15223 for (i
=0;i
<nFreqs
;i
++) inputs
[i
] = 0;
15224 inputs
[which
] = temp
;
15225 sndLevel
*= soundDecay
; // Exponential Sound decay
15226 finalZ
[2] = finalZ
[1];
15227 finalZ
[1] = finalZ
[0];
15229 for (i
=0;i
<nFreqs
;i
++) {
15230 inputs
[i
] -= outputs
[i
][0]*coeffs
[i
][0]; // Do
15231 inputs
[i
] -= outputs
[i
][1]*coeffs
[i
][1]; // resonant
15232 outputs
[i
][1] = outputs
[i
][0]; // filter
15233 outputs
[i
][0] = inputs
[i
]; // calculations
15234 finalZ
[0] += gains
[i
] * outputs
[i
][1];
15236 data
= finalZCoeffs
[0] * finalZ
[0]; // Extra zero(s) for shape
15237 data
+= finalZCoeffs
[1] * finalZ
[1]; // Extra zero(s) for shape
15238 data
+= finalZCoeffs
[2] * finalZ
[2]; // Extra zero(s) for shape
15239 if (data
> 10000.0) data
= 10000.0;
15240 if (data
< -10000.0) data
= -10000.0;
15241 data
= data
* 0.0001;
15246 /***************************************************/
15248 \brief STK wavetable/noise instrument.
15250 This class combines a looped wave, a
15251 noise source, a biquad resonance filter,
15252 a one-pole filter, and an ADSR envelope
15253 to create some interesting sounds.
15255 Control Change Numbers:
15256 - Filter Pole Position = 2
15257 - Noise/Pitched Cross-Fade = 4
15258 - Envelope Rate = 11
15261 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
15263 /***************************************************/
15269 baseFrequency
= (MY_FLOAT
) 440.0;
15271 // Concatenate the STK rawwave path to the rawwave file
15272 loop
= new WaveLoop( "special:impuls10", TRUE
);
15274 filter
= new OnePole(0.5);
15276 biquad
= new BiQuad();
15278 setFrequency(baseFrequency
);
15282 Simple :: ~Simple()
15290 void Simple :: keyOn()
15295 void Simple :: keyOff()
15300 void Simple :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
15303 setFrequency(frequency
);
15304 filter
->setGain(amplitude
);
15306 #if defined(_STK_DEBUG_)
15307 std::cerr
<< "[chuck](via STK): Simple: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
15310 void Simple :: noteOff(MY_FLOAT amplitude
)
15314 #if defined(_STK_DEBUG_)
15315 std::cerr
<< "[chuck](via STK): Simple: NoteOff amplitude = " << amplitude
<< std::endl
;
15319 void Simple :: setFrequency(MY_FLOAT frequency
)
15321 biquad
->setResonance( frequency
, 0.98, true );
15322 loop
->setFrequency(frequency
);
15325 MY_FLOAT
Simple :: tick()
15327 lastOutput
= loopGain
* loop
->tick();
15328 biquad
->tick( noise
->tick() );
15329 lastOutput
+= (1.0 - loopGain
) * biquad
->lastOut();
15330 lastOutput
= filter
->tick( lastOutput
);
15331 lastOutput
*= adsr
->tick();
15335 void Simple :: controlChange(int number
, MY_FLOAT value
)
15337 MY_FLOAT norm
= value
* ONE_OVER_128
;
15340 std::cerr
<< "[chuck](via STK): Clarinet: Control value less than zero!" << std::endl
;
15342 else if ( norm
> 1.0 ) {
15344 std::cerr
<< "[chuck](via STK): Clarinet: Control value greater than 128.0!" << std::endl
;
15347 if (number
== __SK_Breath_
) // 2
15348 filter
->setPole( 0.99 * (1.0 - (norm
* 2.0)) );
15349 else if (number
== __SK_NoiseLevel_
) // 4
15351 else if (number
== __SK_ModFrequency_
) { // 11
15352 norm
/= 0.2 * Stk::sampleRate();
15353 adsr
->setAttackRate( norm
);
15354 adsr
->setDecayRate( norm
);
15355 adsr
->setReleaseRate( norm
);
15357 else if (number
== __SK_AfterTouch_Cont_
) // 128
15358 adsr
->setTarget( norm
);
15360 std::cerr
<< "[chuck](via STK): Simple: Undefined Control Number (" << number
<< ")!!" << std::endl
;
15362 #if defined(_STK_DEBUG_)
15363 std::cerr
<< "[chuck](via STK): Simple: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
15366 /***************************************************/
15367 /*! \class SingWave
15368 \brief STK "singing" looped soundfile class.
15370 This class contains all that is needed to make
15371 a pitched musical sound, like a simple voice
15372 or violin. In general, it will not be used
15373 alone because of munchkinification effects
15374 from pitch shifting. It will be used as an
15375 excitation source for other instruments.
15377 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
15379 /***************************************************/
15382 SingWave :: SingWave(const char *fileName
, bool raw
)
15384 // An exception could be thrown here.
15385 wave
= new WaveLoop( fileName
, raw
);
15389 modulator
= new Modulate();
15390 modulator
->setVibratoRate( 6.0 );
15391 modulator
->setVibratoGain( 0.04 );
15392 modulator
->setRandomGain( 0.005 );
15393 envelope
= new Envelope
;
15394 pitchEnvelope
= new Envelope
;
15395 setFrequency( 75.0 );
15396 pitchEnvelope
->setRate( 1.0 );
15399 pitchEnvelope
->setRate( sweepRate
* rate
);
15402 SingWave :: ~SingWave()
15407 delete pitchEnvelope
;
15410 void SingWave :: reset()
15416 void SingWave :: normalize()
15421 void SingWave :: normalize(MY_FLOAT newPeak
)
15423 wave
->normalize( newPeak
);
15426 void SingWave :: setFrequency(MY_FLOAT frequency
)
15428 m_freq
= frequency
;
15429 MY_FLOAT temp
= rate
;
15430 rate
= wave
->getSize() * frequency
/ Stk::sampleRate();
15432 if ( temp
< 0) temp
= -temp
;
15433 pitchEnvelope
->setTarget( rate
);
15434 pitchEnvelope
->setRate( sweepRate
* temp
);
15437 void SingWave :: setVibratoRate(MY_FLOAT aRate
)
15439 modulator
->setVibratoRate( aRate
);
15442 void SingWave :: setVibratoGain(MY_FLOAT gain
)
15444 modulator
->setVibratoGain(gain
);
15447 void SingWave :: setRandomGain(MY_FLOAT gain
)
15449 modulator
->setRandomGain(gain
);
15452 void SingWave :: setSweepRate(MY_FLOAT aRate
)
15457 void SingWave :: setGainRate(MY_FLOAT aRate
)
15459 envelope
->setRate(aRate
);
15462 void SingWave :: setGainTarget(MY_FLOAT target
)
15464 envelope
->setTarget(target
);
15467 void SingWave :: noteOn()
15472 void SingWave :: noteOff()
15474 envelope
->keyOff();
15477 MY_FLOAT
SingWave :: tick()
15479 // Set the wave rate.
15480 MY_FLOAT newRate
= pitchEnvelope
->tick();
15481 newRate
+= newRate
* modulator
->tick();
15482 wave
->setRate( newRate
);
15484 lastOutput
= wave
->tick();
15485 lastOutput
*= envelope
->tick();
15490 MY_FLOAT
SingWave :: lastOut()
15494 /***************************************************/
15496 \brief STK sitar string model class.
15498 This class implements a sitar plucked string
15499 physical model based on the Karplus-Strong
15502 This is a digital waveguide model, making its
15503 use possibly subject to patents held by
15504 Stanford University, Yamaha, and others.
15505 There exist at least two patents, assigned to
15506 Stanford, bearing the names of Karplus and/or
15509 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
15511 /***************************************************/
15515 Sitar :: Sitar(MY_FLOAT lowestFrequency
)
15517 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
15518 loopGain
= (MY_FLOAT
) 0.999;
15519 delayLine
= new DelayA( (MY_FLOAT
)(length
/ 2.0), length
);
15520 delay
= length
/ 2.0;
15521 targetDelay
= delay
;
15523 loopFilter
= new OneZero
;
15524 loopFilter
->setZero(0.01);
15526 envelope
= new ADSR();
15527 envelope
->setAllTimes(0.001, 0.04, 0.0, 0.5);
15541 void Sitar :: clear()
15543 delayLine
->clear();
15544 loopFilter
->clear();
15547 void Sitar :: setFrequency(MY_FLOAT frequency
)
15549 MY_FLOAT freakency
= frequency
;
15550 if ( frequency
<= 0.0 ) {
15551 std::cerr
<< "[chuck](via STK): Sitar: setFrequency parameter is less than or equal to zero!" << std::endl
;
15555 targetDelay
= (Stk::sampleRate() / freakency
);
15556 delay
= targetDelay
* (1.0 + (0.05 * noise
->tick()));
15557 delayLine
->setDelay(delay
);
15558 loopGain
= 0.995 + (freakency
* 0.0000005);
15559 if (loopGain
> 0.9995) loopGain
= 0.9995;
15562 void Sitar :: pluck(MY_FLOAT amplitude
)
15567 void Sitar :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
15569 setFrequency(frequency
);
15571 amGain
= 0.1 * amplitude
;
15573 #if defined(_STK_DEBUG_)
15574 std::cerr
<< "[chuck](via STK): Sitar: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
15578 void Sitar :: noteOff(MY_FLOAT amplitude
)
15580 loopGain
= (MY_FLOAT
) 1.0 - amplitude
;
15581 if ( loopGain
< 0.0 ) {
15582 std::cerr
<< "[chuck](via STK): Plucked: noteOff amplitude greater than 1.0!" << std::endl
;
15585 else if ( loopGain
> 1.0 ) {
15586 std::cerr
<< "[chuck](via STK): Plucked: noteOff amplitude less than or zero!" << std::endl
;
15587 loopGain
= (MY_FLOAT
) 0.99999;
15590 #if defined(_STK_DEBUG_)
15591 std::cerr
<< "[chuck](via STK): Plucked: NoteOff amplitude = " << amplitude
<< std::endl
;
15595 MY_FLOAT
Sitar :: tick()
15597 if ( fabs(targetDelay
- delay
) > 0.001 ) {
15598 if (targetDelay
< delay
)
15602 delayLine
->setDelay(delay
);
15605 lastOutput
= delayLine
->tick( loopFilter
->tick( delayLine
->lastOut() * loopGain
) +
15606 (amGain
* envelope
->tick() * noise
->tick()));
15610 /***************************************************/
15612 \brief STK sphere class.
15614 This class implements a spherical ball with
15615 radius, mass, position, and velocity parameters.
15617 by Perry R. Cook, 1995 - 2002.
15619 /***************************************************/
15624 Sphere::Sphere(double initRadius
)
15626 myRadius
= initRadius
;
15628 myPosition
= new Vector3D(0, 0, 0);
15629 myVelocity
= new Vector3D(0, 0, 0);
15638 void Sphere::setPosition(double anX
, double aY
, double aZ
)
15640 myPosition
->setXYZ(anX
, aY
, aZ
);
15643 void Sphere::setVelocity(double anX
, double aY
, double aZ
)
15645 myVelocity
->setXYZ(anX
, aY
, aZ
);
15648 void Sphere::setRadius(double aRadius
)
15650 myRadius
= aRadius
;
15653 void Sphere::setMass(double aMass
)
15658 Vector3D
* Sphere::getPosition()
15663 Vector3D
* Sphere::getRelativePosition(Vector3D
* aPosition
)
15665 workingVector
.setXYZ(aPosition
->getX() - myPosition
->getX(),
15666 aPosition
->getY() - myPosition
->getY(),
15667 aPosition
->getZ() - myPosition
->getZ());
15668 return &workingVector
;
15671 double Sphere::getVelocity(Vector3D
* aVelocity
)
15673 aVelocity
->setXYZ(myVelocity
->getX(), myVelocity
->getY(), myVelocity
->getZ());
15674 return myVelocity
->getLength();
15677 double Sphere::isInside(Vector3D
*aPosition
)
15679 // Return directed distance from aPosition to spherical boundary ( <
15682 Vector3D
*tempVector
;
15684 tempVector
= this->getRelativePosition(aPosition
);
15685 distance
= tempVector
->getLength();
15686 return distance
- myRadius
;
15689 double Sphere::getRadius()
15694 double Sphere::getMass()
15699 void Sphere::addVelocity(double anX
, double aY
, double aZ
)
15701 myVelocity
->setX(myVelocity
->getX() + anX
);
15702 myVelocity
->setY(myVelocity
->getY() + aY
);
15703 myVelocity
->setZ(myVelocity
->getZ() + aZ
);
15706 void Sphere::tick(double timeIncrement
)
15708 myPosition
->setX(myPosition
->getX() + (timeIncrement
* myVelocity
->getX()));
15709 myPosition
->setY(myPosition
->getY() + (timeIncrement
* myVelocity
->getY()));
15710 myPosition
->setZ(myPosition
->getZ() + (timeIncrement
* myVelocity
->getZ()));
15713 /***************************************************/
15714 /*! \class StifKarp
15715 \brief STK plucked stiff string instrument.
15717 This class implements a simple plucked string
15718 algorithm (Karplus Strong) with enhancements
15719 (Jaffe-Smith, Smith, and others), including
15720 string stiffness and pluck position controls.
15721 The stiffness is modeled with allpass filters.
15723 This is a digital waveguide model, making its
15724 use possibly subject to patents held by
15725 Stanford University, Yamaha, and others.
15727 Control Change Numbers:
15728 - Pickup Position = 4
15729 - String Sustain = 11
15730 - String Stretch = 1
15732 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
15734 /***************************************************/
15736 #include <string.h>
15739 StifKarp :: StifKarp(MY_FLOAT lowestFrequency
)
15741 length
= (long) (Stk::sampleRate() / lowestFrequency
+ 1);
15742 delayLine
= new DelayA(0.5 * length
, length
);
15743 combDelay
= new DelayL( 0.2 * length
, length
);
15745 filter
= new OneZero();
15746 noise
= new Noise();
15747 biQuad
[0] = new BiQuad();
15748 biQuad
[1] = new BiQuad();
15749 biQuad
[2] = new BiQuad();
15750 biQuad
[3] = new BiQuad();
15752 pluckAmplitude
= 0.3;
15753 pickupPosition
= (MY_FLOAT
) 0.4;
15754 lastFrequency
= lowestFrequency
* 2.0;
15755 lastLength
= length
* 0.5;
15756 stretching
= 0.9999;
15757 baseLoopGain
= 0.995;
15763 StifKarp :: ~StifKarp()
15775 void StifKarp :: clear()
15777 delayLine
->clear();
15778 combDelay
->clear();
15782 void StifKarp :: setFrequency(MY_FLOAT frequency
)
15784 lastFrequency
= frequency
;
15785 if ( frequency
<= 0.0 ) {
15786 std::cerr
<< "[chuck](via STK): StifKarp: setFrequency parameter is less than or equal to zero!" << std::endl
;
15787 lastFrequency
= 220.0;
15790 lastLength
= Stk::sampleRate() / lastFrequency
;
15791 MY_FLOAT delay
= lastLength
- 0.5;
15792 if (delay
<= 0.0) delay
= 0.3;
15793 else if (delay
> length
) delay
= length
;
15794 delayLine
->setDelay( delay
);
15796 loopGain
= baseLoopGain
+ (frequency
* (MY_FLOAT
) 0.000005);
15797 if (loopGain
>= 1.0) loopGain
= (MY_FLOAT
) 0.99999;
15799 setStretch(stretching
);
15801 combDelay
->setDelay((MY_FLOAT
) 0.5 * pickupPosition
* lastLength
);
15804 void StifKarp :: setStretch(MY_FLOAT stretch
)
15806 stretching
= stretch
;
15807 MY_FLOAT coefficient
;
15808 MY_FLOAT freq
= lastFrequency
* 2.0;
15809 MY_FLOAT dFreq
= ( (0.5 * Stk::sampleRate()) - freq
) * 0.25;
15810 MY_FLOAT temp
= 0.5 + (stretch
* 0.5);
15811 if (temp
> 0.9999) temp
= 0.9999;
15812 for (int i
=0; i
<4; i
++) {
15813 coefficient
= temp
* temp
;
15814 biQuad
[i
]->setA2( coefficient
);
15815 biQuad
[i
]->setB0( coefficient
);
15816 biQuad
[i
]->setB2( 1.0 );
15818 coefficient
= -2.0 * temp
* cos(TWO_PI
* freq
/ Stk::sampleRate());
15819 biQuad
[i
]->setA1( coefficient
);
15820 biQuad
[i
]->setB1( coefficient
);
15826 void StifKarp :: setPickupPosition(MY_FLOAT position
) {
15827 pickupPosition
= position
;
15828 if ( position
< 0.0 ) {
15829 std::cerr
<< "[chuck](via STK): StifKarp: setPickupPosition parameter is less than zero!" << std::endl
;
15830 pickupPosition
= 0.0;
15832 else if ( position
> 1.0 ) {
15833 std::cerr
<< "[chuck](via STK): StifKarp: setPickupPosition parameter is greater than 1.0!" << std::endl
;
15834 pickupPosition
= 1.0;
15837 // Set the pick position, which puts zeroes at position * length.
15838 combDelay
->setDelay(0.5 * pickupPosition
* lastLength
);
15841 void StifKarp :: setBaseLoopGain(MY_FLOAT aGain
)
15843 baseLoopGain
= aGain
;
15844 loopGain
= baseLoopGain
+ (lastFrequency
* 0.000005);
15845 if ( loopGain
> 0.99999 ) loopGain
= (MY_FLOAT
) 0.99999;
15848 void StifKarp :: pluck(MY_FLOAT amplitude
)
15850 MY_FLOAT gain
= amplitude
;
15851 if ( gain
> 1.0 ) {
15852 std::cerr
<< "[chuck](via STK): StifKarp: pluck amplitude greater than 1.0!" << std::endl
;
15855 else if ( gain
< 0.0 ) {
15856 std::cerr
<< "[chuck](via STK): StifKarp: pluck amplitude less than zero!" << std::endl
;
15860 pluckAmplitude
= amplitude
;
15861 for (long i
=0; i
<length
; i
++) {
15862 // Fill delay with noise additively with current contents.
15863 delayLine
->tick((delayLine
->lastOut() * 0.6) + 0.4 * noise
->tick() * pluckAmplitude
);
15864 //delayLine->tick( combDelay->tick((delayLine->lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude));
15868 void StifKarp :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
15870 this->setFrequency(frequency
);
15871 this->pluck(amplitude
);
15873 #if defined(_STK_DEBUG_)
15874 std::cerr
<< "[chuck](via STK): StifKarp: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
15878 void StifKarp :: noteOff(MY_FLOAT amplitude
)
15880 MY_FLOAT gain
= amplitude
;
15881 if ( gain
> 1.0 ) {
15882 std::cerr
<< "[chuck](via STK): StifKarp: noteOff amplitude greater than 1.0!" << std::endl
;
15885 else if ( gain
< 0.0 ) {
15886 std::cerr
<< "[chuck](via STK): StifKarp: noteOff amplitude less than zero!" << std::endl
;
15889 loopGain
= (1.0 - gain
) * 0.5;
15891 #if defined(_STK_DEBUG_)
15892 std::cerr
<< "[chuck](via STK): StifPluck: NoteOff amplitude = " << amplitude
<< std::endl
;
15896 MY_FLOAT
StifKarp :: tick()
15898 MY_FLOAT temp
= delayLine
->lastOut() * loopGain
;
15900 // Calculate allpass stretching.
15901 for (int i
=0; i
<4; i
++)
15902 temp
= biQuad
[i
]->tick(temp
);
15904 // Moving average filter.
15905 temp
= filter
->tick(temp
);
15907 lastOutput
= delayLine
->tick(temp
);
15908 lastOutput
= lastOutput
- combDelay
->tick(lastOutput
);
15912 void StifKarp :: controlChange(int number
, MY_FLOAT value
)
15914 MY_FLOAT norm
= value
* ONE_OVER_128
;
15917 std::cerr
<< "[chuck](via STK): StifKarp: Control value less than zero!" << std::endl
;
15919 else if ( norm
> 1.0 ) {
15921 std::cerr
<< "[chuck](via STK): StifKarp: Control value greater than 128.0!" << std::endl
;
15924 if (number
== __SK_PickPosition_
) // 4
15925 setPickupPosition( norm
);
15926 else if (number
== __SK_StringDamping_
) // 11
15927 setBaseLoopGain( 0.97 + (norm
* 0.03) );
15928 else if (number
== __SK_StringDetune_
) // 1
15929 setStretch( 0.9 + (0.1 * (1.0 - norm
)) );
15931 std::cerr
<< "[chuck](via STK): StifKarp: Undefined Control Number (" << number
<< ")!!" << std::endl
;
15933 #if defined(_STK_DEBUG_)
15934 std::cerr
<< "[chuck](via STK): StifKarp: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
15938 /***************************************************/
15940 \brief STK base class
15942 Nearly all STK classes inherit from this class.
15943 The global sample rate can be queried and
15944 modified via Stk. In addition, this class
15945 provides error handling and byte-swapping
15948 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
15950 /***************************************************/
15953 #include <string.h>
15955 MY_FLOAT
Stk :: srate
= (MY_FLOAT
) SRATE
;
15956 std::string
Stk :: rawwavepath
= RAWWAVE_PATH
;
15957 const Stk::STK_FORMAT
Stk :: STK_SINT8
= 1;
15958 const Stk::STK_FORMAT
Stk :: STK_SINT16
= 2;
15959 const Stk::STK_FORMAT
Stk :: STK_SINT32
= 8;
15960 const Stk::STK_FORMAT
Stk :: MY_FLOAT32
= 16;
15961 const Stk::STK_FORMAT
Stk :: MY_FLOAT64
= 32;
15971 MY_FLOAT
Stk :: sampleRate(void)
15976 void Stk :: setSampleRate(MY_FLOAT newRate
)
15982 std::string
Stk :: rawwavePath(void)
15984 return rawwavepath
;
15987 void Stk :: setRawwavePath(std::string newPath
)
15989 if ( !newPath
.empty() )
15990 rawwavepath
= newPath
;
15992 // Make sure the path includes a "/"
15993 if ( rawwavepath
[rawwavepath
.length()-1] != '/' )
15994 rawwavepath
+= "/";
15997 void Stk :: swap16(unsigned char *ptr
)
15999 register unsigned char val
;
16001 // Swap 1st and 2nd bytes
16007 void Stk :: swap32(unsigned char *ptr
)
16009 register unsigned char val
;
16011 // Swap 1st and 4th bytes
16016 //Swap 2nd and 3rd bytes
16023 void Stk :: swap64(unsigned char *ptr
)
16025 register unsigned char val
;
16027 // Swap 1st and 8th bytes
16032 // Swap 2nd and 7th bytes
16038 // Swap 3rd and 6th bytes
16044 // Swap 4th and 5th bytes
16051 #if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__) || defined(__OS_WINDOWS_CYGWIN__))
16052 #include <unistd.h>
16053 #elif defined(__OS_WINDOWS__)
16054 #include <windows.h>
16057 void Stk :: sleep(unsigned long milliseconds
)
16059 #if defined(__OS_WINDOWS__)
16060 Sleep((DWORD
) milliseconds
);
16061 #elif (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__) || defined(__OS_WINDOWS_CYGWIN__))
16062 usleep( (unsigned long) (milliseconds
* 1000.0) );
16066 void Stk :: handleError( const char *message
, StkError::TYPE type
)
16068 if (type
== StkError::WARNING
)
16069 fprintf(stderr
, "%s\n", message
);
16070 else if (type
== StkError::DEBUG_WARNING
) {
16071 #if defined(_STK_DEBUG_)
16072 fprintf(stderr
, "%s\n", message
);
16076 // Print error message before throwing.
16077 fprintf(stderr
, "%s\n", message
);
16078 throw StkError(message
, type
);
16082 StkError :: StkError(const char *p
, TYPE tipe
)
16085 strncpy(message
, p
, 256);
16088 StkError :: ~StkError(void)
16092 void StkError :: printMessage(void)
16094 printf("%s\n", message
);
16096 /***************************************************/
16097 /*! \class SubNoise
16098 \brief STK sub-sampled noise generator.
16100 Generates a new random number every "rate" ticks
16101 using the C rand() function. The quality of the
16102 rand() function varies from one OS to another.
16104 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
16106 /***************************************************/
16109 SubNoise :: SubNoise(int subRate
) : Noise()
16114 SubNoise :: ~SubNoise()
16118 int SubNoise :: subRate(void) const
16123 void SubNoise :: setRate(int subRate
)
16129 MY_FLOAT
SubNoise :: tick()
16131 if ( ++counter
> rate
) {
16138 /***************************************************/
16140 \brief STK table lookup class.
16142 This class loads a table of floating-point
16143 doubles, which are assumed to be in big-endian
16144 format. Linear interpolation is performed for
16145 fractional lookup indexes.
16147 An StkError will be thrown if the table file
16150 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
16152 /***************************************************/
16155 #include <sys/stat.h>
16156 #include <sys/types.h>
16157 #include <iostream>
16159 Table :: Table(char *fileName
)
16163 // Use the system call "stat" to determine the file length
16164 struct stat filestat
;
16165 if ( stat(fileName
, &filestat
) == -1 ) {
16166 sprintf(message
, "[chuck](via Table): Couldn't stat or find file (%s).", fileName
);
16167 handleError( message
, StkError::FILE_NOT_FOUND
);
16169 length
= (long) filestat
.st_size
/ 8; // length in 8-byte samples
16171 // Open the file and read samples into data[]
16173 fd
= fopen(fileName
,"rb");
16175 sprintf(message
, "[chuck](via Table): Couldn't open or find file (%s).", fileName
);
16176 handleError( message
, StkError::FILE_NOT_FOUND
);
16179 data
= (MY_FLOAT
*) new MY_FLOAT
[length
];
16181 // Read samples into data[]
16184 while ( fread(&temp
, 8, 1, fd
) ) {
16185 if( little_endian
)
16186 swap64((unsigned char *)&temp
);
16188 data
[i
++] = (MY_FLOAT
) temp
;
16200 long Table :: getLength() const
16205 MY_FLOAT
Table :: lastOut() const
16210 MY_FLOAT
Table :: tick(MY_FLOAT index
)
16215 if (index
> length
-1) {
16216 std::cerr
<< "[chuck](via STK): Table: Index (" << index
<< ") exceeds table length ... sticking at end!" << std::endl
;
16219 else if (index
< 0.0) {
16220 std::cerr
<< "[chuck](via STK): Table: Index (" << index
<< ") is less than zero ... setting to zero!" << std::endl
;
16224 // Index in range 0 to length-1
16225 temp
= (long) index
; // Integer part of index
16226 alpha
= index
- (MY_FLOAT
) temp
; // Fractional part of index
16227 if (alpha
> 0.0) { // Do linear interpolation
16228 lastOutput
= data
[temp
];
16229 lastOutput
+= (alpha
*(data
[temp
+1] - lastOutput
));
16231 else lastOutput
= data
[temp
];
16236 MY_FLOAT
*Table :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
16238 for (unsigned int i
=0; i
<vectorSize
; i
++)
16239 vector
[i
] = tick(vector
[i
]);
16243 /***************************************************/
16244 /*! \class TubeBell
16245 \brief STK tubular bell (orchestral chime) FM
16246 synthesis instrument.
16248 This class implements two simple FM Pairs
16249 summed together, also referred to as algorithm
16253 Algorithm 5 is : 4->3--\
16258 Control Change Numbers:
16259 - Modulator Index One = 2
16260 - Crossfade of Outputs = 4
16263 - ADSR 2 & 4 Target = 128
16265 The basic Chowning/Stanford FM patent expired
16266 in 1995, but there exist follow-on patents,
16267 mostly assigned to Yamaha. If you are of the
16268 type who should worry about this (making
16271 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
16273 /***************************************************/
16276 TubeBell :: TubeBell()
16279 // Concatenate the STK rawwave path to the rawwave files
16280 for ( int i
=0; i
<3; i
++ )
16281 waves
[i
] = new WaveLoop( "special:sinewave", TRUE
);
16282 waves
[3] = new WaveLoop( "special:fwavblnk", TRUE
);
16284 this->setRatio(0, 1.0 * 0.995);
16285 this->setRatio(1, 1.414 * 0.995);
16286 this->setRatio(2, 1.0 * 1.005);
16287 this->setRatio(3, 1.414 * 1.000);
16289 gains
[0] = __FM_gains
[94];
16290 gains
[1] = __FM_gains
[76];
16291 gains
[2] = __FM_gains
[99];
16292 gains
[3] = __FM_gains
[71];
16294 adsr
[0]->setAllTimes( 0.005, 4.0, 0.0, 0.04);
16295 adsr
[1]->setAllTimes( 0.005, 4.0, 0.0, 0.04);
16296 adsr
[2]->setAllTimes( 0.001, 2.0, 0.0, 0.04);
16297 adsr
[3]->setAllTimes( 0.004, 4.0, 0.0, 0.04);
16299 twozero
->setGain( 0.5 );
16300 vibrato
->setFrequency( 2.0 );
16303 TubeBell :: ~TubeBell()
16307 void TubeBell :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
16309 gains
[0] = amplitude
* __FM_gains
[94];
16310 gains
[1] = amplitude
* __FM_gains
[76];
16311 gains
[2] = amplitude
* __FM_gains
[99];
16312 gains
[3] = amplitude
* __FM_gains
[71];
16313 this->setFrequency(frequency
);
16316 #if defined(_STK_DEBUG_)
16317 cerr
<< "TubeBell: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< endl
;
16321 MY_FLOAT
TubeBell :: tick()
16323 MY_FLOAT temp
, temp2
;
16325 temp
= gains
[1] * adsr
[1]->tick() * waves
[1]->tick();
16326 temp
= temp
* control1
;
16328 waves
[0]->addPhaseOffset(temp
);
16329 waves
[3]->addPhaseOffset(twozero
->lastOut());
16330 temp
= gains
[3] * adsr
[3]->tick() * waves
[3]->tick();
16331 twozero
->tick(temp
);
16333 waves
[2]->addPhaseOffset(temp
);
16334 temp
= ( 1.0 - (control2
* 0.5)) * gains
[0] * adsr
[0]->tick() * waves
[0]->tick();
16335 temp
+= control2
* 0.5 * gains
[2] * adsr
[2]->tick() * waves
[2]->tick();
16337 // Calculate amplitude modulation and apply it to output.
16338 temp2
= vibrato
->tick() * modDepth
;
16339 temp
= temp
* (1.0 + temp2
);
16341 lastOutput
= temp
* 0.5;
16344 /***************************************************/
16346 \brief STK two-pole filter class.
16348 This protected Filter subclass implements
16349 a two-pole digital filter. A method is
16350 provided for creating a resonance in the
16351 frequency response while maintaining a nearly
16352 constant filter gain.
16354 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
16356 /***************************************************/
16360 TwoPole :: TwoPole() : Filter()
16363 MY_FLOAT A
[3] = {1.0, 0.0, 0.0};
16367 Filter::setCoefficients( 1, &B
, 3, A
);
16370 TwoPole :: ~TwoPole()
16374 void TwoPole :: clear(void)
16379 void TwoPole :: setB0(MY_FLOAT b0
)
16384 void TwoPole :: setA1(MY_FLOAT a1
)
16389 void TwoPole :: setA2(MY_FLOAT a2
)
16394 void TwoPole :: setResonance(MY_FLOAT frequency
, MY_FLOAT radius
, bool normalize
)
16396 a
[2] = radius
* radius
;
16397 a
[1] = (MY_FLOAT
) -2.0 * radius
* cos(TWO_PI
* frequency
/ Stk::sampleRate());
16400 // Normalize the filter gain ... not terribly efficient.
16401 MY_FLOAT real
= 1 - radius
+ (a
[2] - radius
) * cos(TWO_PI
* 2 * frequency
/ Stk::sampleRate());
16402 MY_FLOAT imag
= (a
[2] - radius
) * sin(TWO_PI
* 2 * frequency
/ Stk::sampleRate());
16403 b
[0] = sqrt( pow(real
, 2) + pow(imag
, 2) );
16407 void TwoPole :: setGain(MY_FLOAT theGain
)
16409 Filter::setGain(theGain
);
16412 MY_FLOAT
TwoPole :: getGain(void) const
16414 return Filter::getGain();
16417 MY_FLOAT
TwoPole :: lastOut(void) const
16419 return Filter::lastOut();
16422 MY_FLOAT
TwoPole :: tick(MY_FLOAT sample
)
16424 inputs
[0] = gain
* sample
;
16425 outputs
[0] = b
[0] * inputs
[0] - a
[2] * outputs
[2] - a
[1] * outputs
[1];
16426 outputs
[2] = outputs
[1];
16427 outputs
[1] = outputs
[0];
16432 MY_FLOAT
*TwoPole :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
16434 for (unsigned int i
=0; i
<vectorSize
; i
++)
16435 vector
[i
] = tick(vector
[i
]);
16439 /***************************************************/
16441 \brief STK two-zero filter class.
16443 This protected Filter subclass implements
16444 a two-zero digital filter. A method is
16445 provided for creating a "notch" in the
16446 frequency response while maintaining a
16447 constant filter gain.
16449 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
16451 /***************************************************/
16455 TwoZero :: TwoZero() : Filter()
16457 MY_FLOAT B
[3] = {1.0, 0.0, 0.0};
16459 m_notchFreq
= 440.0;
16461 Filter::setCoefficients( 3, B
, 1, &A
);
16464 TwoZero :: ~TwoZero()
16468 void TwoZero :: clear(void)
16473 void TwoZero :: setB0(MY_FLOAT b0
)
16478 void TwoZero :: setB1(MY_FLOAT b1
)
16483 void TwoZero :: setB2(MY_FLOAT b2
)
16488 void TwoZero :: setNotch(MY_FLOAT frequency
, MY_FLOAT radius
)
16490 b
[2] = radius
* radius
;
16491 b
[1] = (MY_FLOAT
) -2.0 * radius
* cos(TWO_PI
* (double) frequency
/ Stk::sampleRate());
16493 // Normalize the filter gain.
16494 if (b
[1] > 0.0) // Maximum at z = 0.
16495 b
[0] = 1.0 / (1.0+b
[1]+b
[2]);
16496 else // Maximum at z = -1.
16497 b
[0] = 1.0 / (1.0-b
[1]+b
[2]);
16502 void TwoZero :: setGain(MY_FLOAT theGain
)
16504 Filter::setGain(theGain
);
16507 MY_FLOAT
TwoZero :: getGain(void) const
16509 return Filter::getGain();
16512 MY_FLOAT
TwoZero :: lastOut(void) const
16514 return Filter::lastOut();
16517 MY_FLOAT
TwoZero :: tick(MY_FLOAT sample
)
16519 inputs
[0] = gain
* sample
;
16520 outputs
[0] = b
[2] * inputs
[2] + b
[1] * inputs
[1] + b
[0] * inputs
[0];
16521 inputs
[2] = inputs
[1];
16522 inputs
[1] = inputs
[0];
16527 MY_FLOAT
*TwoZero :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
16529 for (unsigned int i
=0; i
<vectorSize
; i
++)
16530 vector
[i
] = tick(vector
[i
]);
16534 /***************************************************/
16535 /*! \class Vector3D
16536 \brief STK 3D vector class.
16538 This class implements a three-dimensional vector.
16540 by Perry R. Cook, 1995 - 2002.
16542 /***************************************************/
16546 Vector3D :: Vector3D(double initX
, double initY
, double initZ
)
16553 Vector3D :: ~Vector3D()
16557 double Vector3D :: getX()
16562 double Vector3D :: getY()
16567 double Vector3D :: getZ()
16572 double Vector3D :: getLength()
16582 void Vector3D :: setXYZ(double anX
, double aY
, double aZ
)
16589 void Vector3D :: setX(double aval
)
16594 void Vector3D :: setY(double aval
)
16599 void Vector3D :: setZ(double aval
)
16605 /***************************************************/
16606 /*! \class VoicForm
16607 \brief Four formant synthesis instrument.
16609 This instrument contains an excitation singing
16610 wavetable (looping wave with random and
16611 periodic vibrato, smoothing on frequency,
16612 etc.), excitation noise, and four sweepable
16613 complex resonances.
16615 Measured formant data is included, and enough
16616 data is there to support either parallel or
16617 cascade synthesis. In the floating point case
16618 cascade synthesis is the most natural so
16619 that's what you'll find here.
16621 Control Change Numbers:
16622 - Voiced/Unvoiced Mix = 2
16623 - Vowel/Phoneme Selection = 4
16624 - Vibrato Frequency = 11
16626 - Loudness (Spectral Tilt) = 128
16628 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
16630 /***************************************************/
16635 VoicForm :: VoicForm() : Instrmnt()
16637 // Concatenate the STK rawwave path to the rawwave file
16638 voiced
= new SingWave( "special:impuls20", TRUE
);
16639 voiced
->setGainRate( 0.001 );
16640 voiced
->setGainTarget( 0.0 );
16643 for ( int i
=0; i
<4; i
++ ) {
16644 filters
[i
] = new FormSwep
;
16645 filters
[i
]->setSweepRate( 0.001 );
16648 onezero
= new OneZero
;
16649 onezero
->setZero( -0.9 );
16650 onepole
= new OnePole
;
16651 onepole
->setPole( 0.9 );
16653 noiseEnv
= new Envelope
;
16654 noiseEnv
->setRate( 0.001 );
16655 noiseEnv
->setTarget( 0.0 );
16658 this->setPhoneme( "eee" );
16662 VoicForm :: ~VoicForm()
16669 for ( int i
=0; i
<4; i
++ ) {
16674 void VoicForm :: clear()
16678 for ( int i
=0; i
<4; i
++ ) {
16679 filters
[i
]->clear();
16683 void VoicForm :: setFrequency(MY_FLOAT frequency
)
16685 MY_FLOAT freakency
= frequency
;
16686 if ( frequency
<= 0.0 ) {
16687 std::cerr
<< "[chuck](via STK): VoicForm: setFrequency parameter is less than or equal to zero!" << std::endl
;
16691 voiced
->setFrequency( freakency
);
16694 bool VoicForm :: setPhoneme(const char *phoneme
)
16696 bool found
= false;
16697 unsigned int i
= 0;
16698 while( i
< 32 && !found
) {
16699 if( !strcmp( Phonemes::name(i
), phoneme
) ) {
16701 filters
[0]->setTargets( Phonemes::formantFrequency(i
, 0), Phonemes::formantRadius(i
, 0), pow(10.0, Phonemes::formantGain(i
, 0 ) / 20.0) );
16702 filters
[1]->setTargets( Phonemes::formantFrequency(i
, 1), Phonemes::formantRadius(i
, 1), pow(10.0, Phonemes::formantGain(i
, 1 ) / 20.0) );
16703 filters
[2]->setTargets( Phonemes::formantFrequency(i
, 2), Phonemes::formantRadius(i
, 2), pow(10.0, Phonemes::formantGain(i
, 2 ) / 20.0) );
16704 filters
[3]->setTargets( Phonemes::formantFrequency(i
, 3), Phonemes::formantRadius(i
, 3), pow(10.0, Phonemes::formantGain(i
, 3 ) / 20.0) );
16705 setVoiced( Phonemes::voiceGain( i
) );
16706 setUnVoiced( Phonemes::noiseGain( i
) );
16708 #if defined(_STK_DEBUG_)
16709 std::cerr
<< "[chuck](via STK): VoicForm: found formant " << phoneme
<< " (number " << i
<< ")" << std::endl
;
16716 std::cerr
<< "[chuck](via STK): VoicForm: phoneme " << phoneme
<< " not found!" << std::endl
;
16721 void VoicForm :: setVoiced(MY_FLOAT vGain
)
16723 voiced
->setGainTarget(vGain
);
16726 void VoicForm :: setUnVoiced(MY_FLOAT nGain
)
16728 noiseEnv
->setTarget(nGain
* 0.01);
16731 void VoicForm :: setFilterSweepRate(int whichOne
, MY_FLOAT rate
)
16733 if ( whichOne
< 0 || whichOne
> 3 ) {
16734 std::cerr
<< "[chuck](via STK): VoicForm: setFilterSweepRate filter argument outside range 0-3!" << std::endl
;
16738 filters
[whichOne
]->setSweepRate(rate
);
16741 void VoicForm :: setPitchSweepRate(MY_FLOAT rate
)
16743 voiced
->setSweepRate(rate
);
16746 void VoicForm :: speak()
16751 void VoicForm :: quiet()
16754 noiseEnv
->setTarget( 0.0 );
16757 void VoicForm :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
16759 setFrequency(frequency
);
16760 voiced
->setGainTarget(amplitude
);
16761 onepole
->setPole( 0.97 - (amplitude
* 0.2) );
16764 void VoicForm :: noteOn( MY_FLOAT amplitude
)
16766 voiced
->setGainTarget(amplitude
);
16767 onepole
->setPole( 0.97 - (amplitude
* 0.2) );
16770 void VoicForm :: noteOff(MY_FLOAT amplitude
)
16775 MY_FLOAT
VoicForm :: tick()
16778 temp
= onepole
->tick( onezero
->tick( voiced
->tick() ) );
16779 temp
+= noiseEnv
->tick() * noise
->tick();
16780 lastOutput
= filters
[0]->tick(temp
);
16781 lastOutput
+= filters
[1]->tick(temp
);
16782 lastOutput
+= filters
[2]->tick(temp
);
16783 lastOutput
+= filters
[3]->tick(temp
);
16785 temp += noiseEnv->tick() * noise->tick();
16786 lastOutput = filters[0]->tick(temp);
16787 lastOutput = filters[1]->tick(lastOutput);
16788 lastOutput = filters[2]->tick(lastOutput);
16789 lastOutput = filters[3]->tick(lastOutput);
16794 void VoicForm :: controlChange(int number
, MY_FLOAT value
)
16796 MY_FLOAT norm
= value
* ONE_OVER_128
;
16799 std::cerr
<< "[chuck](via STK): VoicForm: Control value less than zero!" << std::endl
;
16801 else if ( norm
> 1.0 ) {
16803 std::cerr
<< "[chuck](via STK): VoicForm: Control value greater than 128.0!" << std::endl
;
16806 if (number
== __SK_Breath_
) { // 2
16807 this->setVoiced( 1.0 - norm
);
16808 this->setUnVoiced( norm
);
16810 else if (number
== __SK_FootControl_
) { // 4
16811 MY_FLOAT temp
= 0.0;
16812 unsigned int i
= (int) value
;
16824 else if (i
< 128) {
16828 else if (i
== 128) {
16832 filters
[0]->setTargets( temp
* Phonemes::formantFrequency(i
, 0), Phonemes::formantRadius(i
, 0), pow(10.0, Phonemes::formantGain(i
, 0 ) / 20.0) );
16833 filters
[1]->setTargets( temp
* Phonemes::formantFrequency(i
, 1), Phonemes::formantRadius(i
, 1), pow(10.0, Phonemes::formantGain(i
, 1 ) / 20.0) );
16834 filters
[2]->setTargets( temp
* Phonemes::formantFrequency(i
, 2), Phonemes::formantRadius(i
, 2), pow(10.0, Phonemes::formantGain(i
, 2 ) / 20.0) );
16835 filters
[3]->setTargets( temp
* Phonemes::formantFrequency(i
, 3), Phonemes::formantRadius(i
, 3), pow(10.0, Phonemes::formantGain(i
, 3 ) / 20.0) );
16836 setVoiced( Phonemes::voiceGain( i
) );
16837 setUnVoiced( Phonemes::noiseGain( i
) );
16839 else if (number
== __SK_ModFrequency_
) // 11
16840 voiced
->setVibratoRate( norm
* 12.0); // 0 to 12 Hz
16841 else if (number
== __SK_ModWheel_
) // 1
16842 voiced
->setVibratoGain( norm
* 0.2);
16843 else if (number
== __SK_AfterTouch_Cont_
) { // 128
16845 onepole
->setPole( 0.97 - ( norm
* 0.2) );
16848 std::cerr
<< "[chuck](via STK): VoicForm: Undefined Control Number (" << number
<< ")!!" << std::endl
;
16850 #if defined(_STK_DEBUG_)
16851 std::cerr
<< "[chuck](via STK): VoicForm: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
16854 /***************************************************/
16856 \brief STK voice manager class.
16858 This class can be used to manage a group of
16859 STK instrument classes. Individual voices can
16860 be controlled via unique note tags.
16861 Instrument groups can be controlled by channel
16864 A previously constructed STK instrument class
16865 is linked with a voice manager using the
16866 addInstrument() function. An optional channel
16867 number argument can be specified to the
16868 addInstrument() function as well (default
16869 channel = 0). The voice manager does not
16870 delete any instrument instances ... it is the
16871 responsibility of the user to allocate and
16872 deallocate all instruments.
16874 The tick() function returns the mix of all
16875 sounding voices. Each noteOn returns a unique
16876 tag (credits to the NeXT MusicKit), so you can
16877 send control changes to specific voices within
16878 an ensemble. Alternately, control changes can
16879 be sent to all voices on a given channel.
16881 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
16883 /***************************************************/
16885 #include <stdlib.h>
16888 Voicer :: Voicer( int maxInstruments
, MY_FLOAT decayTime
)
16891 maxVoices
= maxInstruments
;
16892 voices
= (Voice
*) new Voice
[maxVoices
];
16894 muteTime
= (int) ( decayTime
* Stk::sampleRate() );
16897 Voicer :: ~Voicer()
16902 void Voicer :: addInstrument( Instrmnt
*instrument
, int channel
)
16904 //voices = (Voice *) realloc( (void *) voices, nVoices+1 * sizeof( Voice ) );
16905 if ( nVoices
== maxVoices
) {
16906 std::cerr
<< "[chuck](via STK): Voicer: Maximum number of voices already added!!" << std::endl
;
16910 voices
[nVoices
].instrument
= instrument
;
16911 voices
[nVoices
].tag
= 0;
16912 voices
[nVoices
].channel
= channel
;
16913 voices
[nVoices
].noteNumber
= -1;
16914 voices
[nVoices
].frequency
= 0.0;
16915 voices
[nVoices
].sounding
= 0;
16919 void Voicer :: removeInstrument( Instrmnt
*instrument
)
16921 bool found
= false;
16922 for ( int i
=0; i
<nVoices
; i
++ ) {
16923 if ( voices
[i
].instrument
== instrument
) found
= true;
16924 if ( found
&& i
+1 < nVoices
) {
16925 voices
[i
].instrument
= voices
[i
+1].instrument
;
16926 voices
[i
].tag
= voices
[i
+1].tag
;
16927 voices
[i
].noteNumber
= voices
[i
+1].noteNumber
;
16928 voices
[i
].frequency
= voices
[i
+1].frequency
;
16929 voices
[i
].sounding
= voices
[i
+1].sounding
;
16930 voices
[i
].channel
= voices
[i
+1].channel
;
16936 //voices = (Voice *) realloc( voices, --nVoices * sizeof( Voice ) );
16940 long Voicer :: noteOn(MY_FLOAT noteNumber
, MY_FLOAT amplitude
, int channel
)
16943 MY_FLOAT frequency
= (MY_FLOAT
) 220.0 * pow( 2.0, (noteNumber
- 57.0) / 12.0 );
16944 for ( i
=0; i
<nVoices
; i
++ ) {
16945 if (voices
[i
].noteNumber
< 0 && voices
[i
].channel
== channel
) {
16946 voices
[i
].tag
= tags
++;
16947 voices
[i
].channel
= channel
;
16948 voices
[i
].noteNumber
= noteNumber
;
16949 voices
[i
].frequency
= frequency
;
16950 voices
[i
].instrument
->noteOn( frequency
, amplitude
* ONE_OVER_128
);
16951 voices
[i
].sounding
= 1;
16952 return voices
[i
].tag
;
16956 // All voices are sounding, so interrupt the oldest voice.
16958 for ( i
=0; i
<nVoices
; i
++ ) {
16959 if ( voices
[i
].channel
== channel
) {
16960 if ( voice
== -1 ) voice
= i
;
16961 else if ( voices
[i
].tag
< voices
[voice
].tag
) voice
= i
;
16965 if ( voice
>= 0 ) {
16966 voices
[voice
].tag
= tags
++;
16967 voices
[voice
].channel
= channel
;
16968 voices
[voice
].noteNumber
= noteNumber
;
16969 voices
[voice
].frequency
= frequency
;
16970 voices
[voice
].instrument
->noteOn( frequency
, amplitude
* ONE_OVER_128
);
16971 voices
[voice
].sounding
= 1;
16972 return voices
[voice
].tag
;
16978 void Voicer :: noteOff( MY_FLOAT noteNumber
, MY_FLOAT amplitude
, int channel
)
16980 for ( int i
=0; i
<nVoices
; i
++ ) {
16981 if ( voices
[i
].noteNumber
== noteNumber
&& voices
[i
].channel
== channel
) {
16982 voices
[i
].instrument
->noteOff( amplitude
* ONE_OVER_128
);
16983 voices
[i
].sounding
= -muteTime
;
16988 void Voicer :: noteOff( long tag
, MY_FLOAT amplitude
)
16990 for ( int i
=0; i
<nVoices
; i
++ ) {
16991 if ( voices
[i
].tag
== tag
) {
16992 voices
[i
].instrument
->noteOff( amplitude
* ONE_OVER_128
);
16993 voices
[i
].sounding
= -muteTime
;
16999 void Voicer :: setFrequency( MY_FLOAT noteNumber
, int channel
)
17001 MY_FLOAT frequency
= (MY_FLOAT
) 220.0 * pow( 2.0, (noteNumber
- 57.0) / 12.0 );
17002 for ( int i
=0; i
<nVoices
; i
++ ) {
17003 if ( voices
[i
].channel
== channel
) {
17004 voices
[i
].noteNumber
= noteNumber
;
17005 voices
[i
].frequency
= frequency
;
17006 voices
[i
].instrument
->setFrequency( frequency
);
17011 void Voicer :: setFrequency( long tag
, MY_FLOAT noteNumber
)
17013 MY_FLOAT frequency
= (MY_FLOAT
) 220.0 * pow( 2.0, (noteNumber
- 57.0) / 12.0 );
17014 for ( int i
=0; i
<nVoices
; i
++ ) {
17015 if ( voices
[i
].tag
== tag
) {
17016 voices
[i
].noteNumber
= noteNumber
;
17017 voices
[i
].frequency
= frequency
;
17018 voices
[i
].instrument
->setFrequency( frequency
);
17024 void Voicer :: pitchBend( MY_FLOAT value
, int channel
)
17026 MY_FLOAT pitchScaler
;
17027 if ( value
< 64.0 )
17028 pitchScaler
= pow(0.5, (64.0-value
)/64.0);
17030 pitchScaler
= pow(2.0, (value
-64.0)/64.0);
17031 for ( int i
=0; i
<nVoices
; i
++ ) {
17032 if ( voices
[i
].channel
== channel
)
17033 voices
[i
].instrument
->setFrequency( (MY_FLOAT
) (voices
[i
].frequency
* pitchScaler
) );
17037 void Voicer :: pitchBend( long tag
, MY_FLOAT value
)
17039 MY_FLOAT pitchScaler
;
17040 if ( value
< 64.0 )
17041 pitchScaler
= pow(0.5, (64.0-value
)/64.0);
17043 pitchScaler
= pow(2.0, (value
-64.0)/64.0);
17044 for ( int i
=0; i
<nVoices
; i
++ ) {
17045 if ( voices
[i
].tag
== tag
) {
17046 voices
[i
].instrument
->setFrequency( (MY_FLOAT
) (voices
[i
].frequency
* pitchScaler
) );
17052 void Voicer :: controlChange( int number
, MY_FLOAT value
, int channel
)
17054 for ( int i
=0; i
<nVoices
; i
++ ) {
17055 if ( voices
[i
].channel
== channel
)
17056 voices
[i
].instrument
->controlChange( number
, value
);
17060 void Voicer :: controlChange( long tag
, int number
, MY_FLOAT value
)
17062 for ( int i
=0; i
<nVoices
; i
++ ) {
17063 if ( voices
[i
].tag
== tag
) {
17064 voices
[i
].instrument
->controlChange( number
, value
);
17070 void Voicer :: silence( void )
17072 for ( int i
=0; i
<nVoices
; i
++ ) {
17073 if ( voices
[i
].sounding
> 0 )
17074 voices
[i
].instrument
->noteOff( 0.5 );
17078 MY_FLOAT
Voicer :: tick()
17080 lastOutput
= lastOutputLeft
= lastOutputRight
= 0.0;
17081 for ( int i
=0; i
<nVoices
; i
++ ) {
17082 if ( voices
[i
].sounding
!= 0 ) {
17083 lastOutput
+= voices
[i
].instrument
->tick();
17084 lastOutputLeft
+= voices
[i
].instrument
->lastOutLeft();
17085 lastOutputRight
+= voices
[i
].instrument
->lastOutRight();
17087 if ( voices
[i
].sounding
< 0 ) {
17088 voices
[i
].sounding
++;
17089 if ( voices
[i
].sounding
== 0 )
17090 voices
[i
].noteNumber
= -1;
17093 return lastOutput
/ nVoices
;
17096 MY_FLOAT
*Voicer :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
17098 for (unsigned int i
=0; i
<vectorSize
; i
++)
17099 vector
[i
] = tick();
17104 MY_FLOAT
Voicer :: lastOut() const
17109 MY_FLOAT
Voicer :: lastOutLeft() const
17111 return lastOutputLeft
;
17114 MY_FLOAT
Voicer :: lastOutRight() const
17116 return lastOutputRight
;
17119 /***************************************************/
17120 /*! \class WaveLoop
17121 \brief STK waveform oscillator class.
17123 This class inherits from WvIn and provides
17124 audio file looping functionality.
17126 WaveLoop supports multi-channel data in
17127 interleaved format. It is important to
17128 distinguish the tick() methods, which return
17129 samples produced by averaging across sample
17130 frames, from the tickFrame() methods, which
17131 return pointers to multi-channel sample frames.
17132 For single-channel data, these methods return
17135 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
17137 /***************************************************/
17141 WaveLoop :: WaveLoop( const char *fileName
, bool raw
, bool generate
)
17142 : WvIn( fileName
, raw
), phaseOffset(0.0)
17145 // If at end of file, redo extra sample frame for looping.
17146 if (chunkPointer
+bufferSize
== fileSize
) {
17147 for (unsigned int j
=0; j
<channels
; j
++)
17148 data
[bufferSize
*channels
+j
] = data
[j
];
17153 WaveLoop :: WaveLoop( )
17154 : WvIn( ), phaseOffset(0.0)
17158 WaveLoop :: openFile( const char * fileName
, bool raw
, bool norm
)
17161 WvIn::openFile( fileName
, raw
, norm
);
17162 // If at end of file, redo extra sample frame for looping.
17163 if (chunkPointer
+bufferSize
== fileSize
) {
17164 for (unsigned int j
=0; j
<channels
; j
++)
17165 data
[bufferSize
*channels
+j
] = data
[j
];
17170 WaveLoop :: ~WaveLoop()
17175 void WaveLoop :: readData( unsigned long index
)
17177 WvIn::readData( index
);
17179 // If at end of file, redo extra sample frame for looping.
17180 if (chunkPointer
+bufferSize
== fileSize
) {
17181 for (unsigned int j
=0; j
<channels
; j
++)
17182 data
[bufferSize
*channels
+j
] = data
[j
];
17186 void WaveLoop :: setFrequency(MY_FLOAT aFrequency
)
17188 // This is a looping frequency.
17189 m_freq
= aFrequency
; // chuck data
17191 rate
= fileSize
* aFrequency
/ sampleRate();
17194 void WaveLoop :: addTime(MY_FLOAT aTime
)
17196 // Add an absolute time in samples
17201 while (time
>= fileSize
)
17205 void WaveLoop :: addPhase(MY_FLOAT anAngle
)
17207 // Add a time in cycles (one cycle = fileSize).
17208 time
+= fileSize
* anAngle
;
17212 while (time
>= fileSize
)
17216 void WaveLoop :: addPhaseOffset(MY_FLOAT anAngle
)
17218 // Add a phase offset in cycles, where 1.0 = fileSize.
17219 phaseOffset
= fileSize
* anAngle
;
17222 const MY_FLOAT
*WaveLoop :: tickFrame(void)
17224 register MY_FLOAT tyme
, alpha
;
17225 register unsigned long i
, index
;
17227 // Check limits of time address ... if necessary, recalculate modulo fileSize.
17230 while (time
>= fileSize
)
17234 tyme
= time
+ phaseOffset
;
17237 while (tyme
>= fileSize
)
17245 // Check the time address vs. our current buffer limits.
17246 if ( (tyme
< chunkPointer
) || (tyme
>= chunkPointer
+bufferSize
) )
17247 this->readData((long) tyme
);
17248 // Adjust index for the current buffer.
17249 tyme
-= chunkPointer
;
17252 // Always do linear interpolation here ... integer part of time address.
17253 index
= (unsigned long) tyme
;
17255 // Fractional part of time address.
17256 alpha
= tyme
- (MY_FLOAT
) index
;
17258 for (i
=0; i
<channels
; i
++) {
17259 lastOutput
[i
] = data
[index
];
17260 lastOutput
[i
] += (alpha
* (data
[index
+channels
] - lastOutput
[i
]));
17265 // Scale outputs by gain.
17266 for (i
=0; i
<channels
; i
++) lastOutput
[i
] *= gain
;
17269 // Increment time, which can be negative.
17275 /***************************************************/
17277 \brief STK police/referee whistle instrument class.
17279 This class implements a hybrid physical/spectral
17280 model of a police whistle (a la Cook).
17282 Control Change Numbers:
17284 - Fipple Modulation Frequency = 11
17285 - Fipple Modulation Gain = 1
17286 - Blowing Frequency Modulation = 2
17289 by Perry R. Cook 1996 - 2002.
17291 /***************************************************/
17293 #include <stdlib.h>
17296 #define CAN_RADIUS 100
17297 #define PEA_RADIUS 30
17298 #define BUMP_RADIUS 5
17300 #define NORM_CAN_LOSS 0.97
17301 #define SLOW_CAN_LOSS 0.90
17302 #define GRAVITY 20.0
17305 #define NORM_TICK_SIZE 0.004
17306 #define SLOW_TICK_SIZE 0.0001
17308 #define ENV_RATE 0.001
17310 Whistle :: Whistle()
17312 tempVector
= new Vector3D(0,0,0);
17313 can
= new Sphere(CAN_RADIUS
);
17314 pea
= new Sphere(PEA_RADIUS
);
17315 bumper
= new Sphere(BUMP_RADIUS
);
17317 // Concatenate the STK rawwave path to the rawwave file
17318 sine
= new WaveLoop( "special:sinewave", TRUE
);
17319 sine
->setFrequency(2800.0);
17321 can
->setPosition(0, 0, 0); // set can location
17322 can
->setVelocity(0, 0, 0); // and the velocity
17324 onepole
.setPole(0.95); // 0.99
17326 bumper
->setPosition(0.0, CAN_RADIUS
-BUMP_RADIUS
, 0);
17327 bumper
->setPosition(0.0, CAN_RADIUS
-BUMP_RADIUS
, 0);
17328 pea
->setPosition(0, CAN_RADIUS
/2, 0);
17329 pea
->setVelocity(35, 15, 0);
17331 envelope
.setRate(ENV_RATE
);
17334 fippleFreqMod
= 0.5;
17335 fippleGainMod
= 0.5;
17336 blowFreqMod
= 0.25;
17338 maxPressure
= (MY_FLOAT
) 0.0;
17339 baseFrequency
= 2000;
17341 tickSize
= NORM_TICK_SIZE
;
17342 canLoss
= NORM_CAN_LOSS
;
17345 subSampCount
= subSample
;
17348 Whistle :: ~Whistle()
17357 void Whistle :: clear()
17361 void Whistle :: setFrequency(MY_FLOAT frequency
)
17363 MY_FLOAT freakency
= frequency
* 4; // the whistle is a transposing instrument
17364 if ( frequency
<= 0.0 ) {
17365 std::cerr
<< "[chuck](via STK): Whistle: setFrequency parameter is less than or equal to zero!" << std::endl
;
17369 baseFrequency
= freakency
;
17372 void Whistle :: startBlowing(MY_FLOAT amplitude
, MY_FLOAT rate
)
17374 envelope
.setRate(ENV_RATE
);
17375 envelope
.setTarget(amplitude
);
17378 void Whistle :: stopBlowing(MY_FLOAT rate
)
17380 envelope
.setRate(rate
);
17384 void Whistle :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
17386 setFrequency(frequency
);
17387 startBlowing(amplitude
*2.0 ,amplitude
* 0.2);
17388 #if defined(_STK_DEBUG_)
17389 std::cerr
<< "[chuck](via STK): Whistle: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< std::endl
;
17393 void Whistle :: noteOff(MY_FLOAT amplitude
)
17395 this->stopBlowing(amplitude
* 0.02);
17397 #if defined(_STK_DEBUG_)
17398 std::cerr
<< "[chuck](via STK): Whistle: NoteOff amplitude = " << amplitude
<< std::endl
;
17402 int frameCount
= 0;
17404 MY_FLOAT
Whistle :: tick()
17406 MY_FLOAT soundMix
, tempFreq
;
17407 double envOut
= 0, temp
, temp1
, temp2
, tempX
, tempY
;
17408 double phi
, cosphi
, sinphi
;
17409 double gain
= 0.5, mod
= 0.0;
17411 if (--subSampCount
<= 0) {
17412 tempVectorP
= pea
->getPosition();
17413 subSampCount
= subSample
;
17414 temp
= bumper
->isInside(tempVectorP
);
17415 #ifdef WHISTLE_ANIMATION
17417 if (frameCount
>= (1470 / subSample
)) {
17419 // printf("%f %f %f\n",tempVectorP->getX(),tempVectorP->getY(),envOut);
17423 envOut
= envelope
.tick();
17425 if (temp
< (BUMP_RADIUS
+ PEA_RADIUS
)) {
17426 tempX
= envOut
* tickSize
* 2000 * noise
.tick();
17427 tempY
= -envOut
* tickSize
* 1000 * (1.0 + noise
.tick());
17428 pea
->addVelocity(tempX
,tempY
,0);
17429 pea
->tick(tickSize
);
17432 mod
= exp(-temp
* 0.01); // exp. distance falloff of fipple/pea effect
17433 temp
= onepole
.tick(mod
); // smooth it a little
17434 gain
= (1.0 - (fippleGainMod
*0.5)) + (2.0 * fippleGainMod
* temp
);
17435 gain
*= gain
; // squared distance/gain
17436 // tempFreq = 1.0 // Normalized Base Freq
17437 // + (fippleFreqMod * 0.25) - (fippleFreqMod * temp) // fippleModulation
17438 // - (blowFreqMod) + (blowFreqMod * envOut); // blowingModulation
17439 // short form of above
17440 tempFreq
= 1.0 + fippleFreqMod
*(0.25-temp
) + blowFreqMod
*(envOut
-1.0);
17441 tempFreq
*= baseFrequency
;
17443 sine
->setFrequency(tempFreq
);
17445 tempVectorP
= pea
->getPosition();
17446 temp
= can
->isInside(tempVectorP
);
17447 temp
= -temp
; // We know (hope) it's inside, just how much??
17448 if (temp
< (PEA_RADIUS
* 1.25)) {
17449 pea
->getVelocity(tempVector
); // This is the can/pea collision
17450 tempX
= tempVectorP
->getX(); // calculation. Could probably
17451 tempY
= tempVectorP
->getY(); // simplify using tables, etc.
17452 phi
= -atan2(tempY
,tempX
);
17455 temp1
= (cosphi
*tempVector
->getX()) - (sinphi
*tempVector
->getY());
17456 temp2
= (sinphi
*tempVector
->getX()) + (cosphi
*tempVector
->getY());
17458 tempX
= (cosphi
*temp1
) + (sinphi
*temp2
);
17459 tempY
= (-sinphi
*temp1
) + (cosphi
*temp2
);
17460 pea
->setVelocity(tempX
, tempY
, 0);
17461 pea
->tick(tickSize
);
17462 pea
->setVelocity(tempX
*canLoss
, tempY
*canLoss
, 0);
17463 pea
->tick(tickSize
);
17466 temp
= tempVectorP
->getLength();
17468 tempX
= tempVectorP
->getX();
17469 tempY
= tempVectorP
->getY();
17470 phi
= atan2(tempY
,tempX
);
17471 phi
+= 0.3 * temp
/ CAN_RADIUS
;
17474 tempX
= 3.0 * temp
* cosphi
;
17475 tempY
= 3.0 * temp
* sinphi
;
17482 temp
= (0.9 + 0.1*subSample
*noise
.tick()) * envOut
* 0.6 * tickSize
;
17483 pea
->addVelocity(temp
* tempX
,
17484 (temp
*tempY
) - (GRAVITY
*tickSize
),0);
17485 pea
->tick(tickSize
);
17487 // bumper->tick(0.0);
17490 temp
= envOut
* envOut
* gain
/ 2;
17491 soundMix
= temp
* (sine
->tick() + (noiseGain
*noise
.tick()));
17492 lastOutput
= 0.25 * soundMix
; // should probably do one-zero filter here
17497 void Whistle :: controlChange(int number
, MY_FLOAT value
)
17499 MY_FLOAT norm
= value
* ONE_OVER_128
;
17502 std::cerr
<< "[chuck](via STK): Whistle: Control value less than zero!" << std::endl
;
17504 else if ( norm
> 1.0 ) {
17506 std::cerr
<< "[chuck](via STK): Whistle: Control value greater than 128.0!" << std::endl
;
17509 if (number
== __SK_NoiseLevel_
) // 4
17510 noiseGain
= 0.25 * norm
;
17511 else if (number
== __SK_ModFrequency_
) // 11
17512 fippleFreqMod
= norm
;
17513 else if (number
== __SK_ModWheel_
) // 1
17514 fippleGainMod
= norm
;
17515 else if (number
== __SK_AfterTouch_Cont_
) // 128
17516 envelope
.setTarget( norm
* 2.0 );
17517 else if (number
== __SK_Breath_
) // 2
17518 blowFreqMod
= norm
* 0.5;
17519 else if (number
== __SK_Sustain_
) // 64
17520 if (value
< 1.0) subSample
= 1;
17522 std::cerr
<< "[chuck](via STK): Whistle: Undefined Control Number (" << number
<< ")!!" << std::endl
;
17524 #if defined(_STK_DEBUG_)
17525 std::cerr
<< "[chuck](via STK): Whistle: controlChange number = " << number
<< ", value = " << value
<< std::endl
;
17529 /***************************************************/
17531 \brief STK Wurlitzer electric piano FM
17532 synthesis instrument.
17534 This class implements two simple FM Pairs
17535 summed together, also referred to as algorithm
17539 Algorithm 5 is : 4->3--\
17544 Control Change Numbers:
17545 - Modulator Index One = 2
17546 - Crossfade of Outputs = 4
17549 - ADSR 2 & 4 Target = 128
17551 The basic Chowning/Stanford FM patent expired
17552 in 1995, but there exist follow-on patents,
17553 mostly assigned to Yamaha. If you are of the
17554 type who should worry about this (making
17557 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
17559 /***************************************************/
17565 // Concatenate the STK rawwave path to the rawwave files
17566 for ( int i
=0; i
<3; i
++ )
17567 waves
[i
] = new WaveLoop( "special:sinewave", TRUE
);
17568 waves
[3] = new WaveLoop( "special:fwavblnk", TRUE
);
17570 this->setRatio(0, 1.0);
17571 this->setRatio(1, 4.0);
17572 this->setRatio(2, -510.0);
17573 this->setRatio(3, -510.0);
17575 gains
[0] = __FM_gains
[99];
17576 gains
[1] = __FM_gains
[82];
17577 gains
[2] = __FM_gains
[92];
17578 gains
[3] = __FM_gains
[68];
17580 adsr
[0]->setAllTimes( 0.001, 1.50, 0.0, 0.04);
17581 adsr
[1]->setAllTimes( 0.001, 1.50, 0.0, 0.04);
17582 adsr
[2]->setAllTimes( 0.001, 0.25, 0.0, 0.04);
17583 adsr
[3]->setAllTimes( 0.001, 0.15, 0.0, 0.04);
17585 twozero
->setGain( 2.0 );
17586 vibrato
->setFrequency( 8.0 );
17589 Wurley :: ~Wurley()
17593 void Wurley :: setFrequency(MY_FLOAT frequency
)
17595 baseFrequency
= frequency
;
17596 waves
[0]->setFrequency(baseFrequency
* ratios
[0]);
17597 waves
[1]->setFrequency(baseFrequency
* ratios
[1]);
17598 waves
[2]->setFrequency(ratios
[2]); // Note here a 'fixed resonance'.
17599 waves
[3]->setFrequency(ratios
[3]);
17602 void Wurley :: noteOn(MY_FLOAT frequency
, MY_FLOAT amplitude
)
17604 gains
[0] = amplitude
* __FM_gains
[99];
17605 gains
[1] = amplitude
* __FM_gains
[82];
17606 gains
[2] = amplitude
* __FM_gains
[82];
17607 gains
[3] = amplitude
* __FM_gains
[68];
17608 this->setFrequency(frequency
);
17611 #if defined(_STK_DEBUG_)
17612 cerr
<< "Wurley: NoteOn frequency = " << frequency
<< ", amplitude = " << amplitude
<< endl
;
17616 MY_FLOAT
Wurley :: tick()
17618 MY_FLOAT temp
, temp2
;
17620 temp
= gains
[1] * adsr
[1]->tick() * waves
[1]->tick();
17621 temp
= temp
* control1
;
17623 waves
[0]->addPhaseOffset(temp
);
17624 waves
[3]->addPhaseOffset(twozero
->lastOut());
17625 temp
= gains
[3] * adsr
[3]->tick() * waves
[3]->tick();
17626 twozero
->tick(temp
);
17628 waves
[2]->addPhaseOffset(temp
);
17629 temp
= ( 1.0 - (control2
* 0.5)) * gains
[0] * adsr
[0]->tick() * waves
[0]->tick();
17630 temp
+= control2
* 0.5 * gains
[2] * adsr
[2]->tick() * waves
[2]->tick();
17632 // Calculate amplitude modulation and apply it to output.
17633 temp2
= vibrato
->tick() * modDepth
;
17634 temp
= temp
* (1.0 + temp2
);
17636 lastOutput
= temp
* 0.5;
17639 /***************************************************/
17641 \brief STK audio data input base class.
17643 This class provides input support for various
17644 audio file formats. It also serves as a base
17645 class for "realtime" streaming subclasses.
17647 WvIn loads the contents of an audio file for
17648 subsequent output. Linear interpolation is
17649 used for fractional "read rates".
17651 WvIn supports multi-channel data in interleaved
17652 format. It is important to distinguish the
17653 tick() methods, which return samples produced
17654 by averaging across sample frames, from the
17655 tickFrame() methods, which return pointers to
17656 multi-channel sample frames. For single-channel
17657 data, these methods return equivalent values.
17659 Small files are completely read into local memory
17660 during instantiation. Large files are read
17661 incrementally from disk. The file size threshold
17662 and the increment size values are defined in
17665 WvIn currently supports WAV, AIFF, SND (AU),
17666 MAT-file (Matlab), and STK RAW file formats.
17667 Signed integer (8-, 16-, and 32-bit) and floating-
17668 point (32- and 64-bit) data types are supported.
17669 Uncompressed data types are not supported. If
17670 using MAT-files, data should be saved in an array
17671 with each data channel filling a matrix row.
17673 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
17675 /***************************************************/
17677 #include <sys/stat.h>
17678 #include <sys/types.h>
17680 #include <string.h>
17682 #include <iostream>
17684 #include "util_raw.h"
17691 WvIn :: WvIn( const char *fileName
, bool raw
, bool doNormalize
, bool generate
)
17694 openFile( fileName
, raw
, generate
);
17706 delete [] lastOutput
;
17711 void WvIn :: init( void )
17715 strcpy ( m_filename
, "" );
17720 interpolate
= false;
17726 void WvIn :: closeFile( void )
17728 if ( fd
) fclose( fd
);
17732 void WvIn :: openFile( const char *fileName
, bool raw
, bool doNormalize
, bool generate
)
17734 unsigned long lastChannels
= channels
;
17735 unsigned long samples
, lastSamples
= (bufferSize
+1)*channels
;
17736 strncpy ( m_filename
, fileName
, 255 );
17737 m_filename
[0] = '0';
17738 if(!generate
|| !strstr(fileName
, "special:"))
17742 // Try to open the file.
17743 fd
= fopen(fileName
, "rb");
17745 sprintf(msg
, "[chuck](via WvIn): Could not open or find file (%s).", fileName
);
17746 handleError(msg
, StkError::FILE_NOT_FOUND
);
17749 bool result
= false;
17751 result
= getRawInfo( fileName
);
17754 if ( fread(&header
, 4, 3, fd
) != 3 ) goto error
;
17755 if ( !strncmp(header
, "RIFF", 4) &&
17756 !strncmp(&header
[8], "WAVE", 4) )
17757 result
= getWavInfo( fileName
);
17758 else if ( !strncmp(header
, ".snd", 4) )
17759 result
= getSndInfo( fileName
);
17760 else if ( !strncmp(header
, "FORM", 4) &&
17761 (!strncmp(&header
[8], "AIFF", 4) || !strncmp(&header
[8], "AIFC", 4) ) )
17762 result
= getAifInfo( fileName
);
17764 if ( fseek(fd
, 126, SEEK_SET
) == -1 ) goto error
;
17765 if ( fread(&header
, 2, 1, fd
) != 1 ) goto error
;
17766 if (!strncmp(header
, "MI", 2) ||
17767 !strncmp(header
, "IM", 2) )
17768 result
= getMatInfo( fileName
);
17771 result
= getRawInfo( fileName
);
17772 // sprintf(msg, "WvIn: File (%s) format unknown.", fileName);
17773 // handleError(msg, StkError::FILE_UNKNOWN_FORMAT);
17778 if ( result
== false )
17779 handleError(msg
, StkError::FILE_ERROR
);
17781 if ( fileSize
== 0 ) {
17782 sprintf(msg
, "[chuck](via WvIn): File (%s) data size is zero!", fileName
);
17783 handleError(msg
, StkError::FILE_ERROR
);
17792 // Allocate new memory if necessary.
17793 samples
= (bufferSize
+1)*channels
;
17794 if ( lastSamples
< samples
) {
17795 if ( data
) delete [] data
;
17796 data
= (MY_FLOAT
*) new MY_FLOAT
[samples
];
17798 if ( lastChannels
< channels
) {
17799 if ( lastOutput
) delete [] lastOutput
;
17800 lastOutput
= (MY_FLOAT
*) new MY_FLOAT
[channels
];
17803 if ( fmod(rate
, 1.0) != 0.0 ) interpolate
= true;
17807 if(generate
&& strstr(fileName
, "special:"))
17809 // STK rawwave files have no header and are assumed to contain a
17810 // monophonic stream of 16-bit signed integers in big-endian byte
17811 // order with a sample rate of 22050 Hz.
17812 fileSize
= bufferSize
;
17814 interpolate
= true;
17816 dataType
= STK_SINT16
;
17818 fileRate
= 22050.0;
17819 rate
= (MY_FLOAT
)fileRate
/ Stk::sampleRate();
17823 if( strstr(fileName
, "special:sinewave") )
17825 for (unsigned int j
=0; j
<bufferSize
; j
++)
17826 data
[j
] = (SHRT_MAX
) * sin(2*PI
*j
/256);
17830 SAMPLE
* rawdata
= NULL
;
17833 if( strstr(fileName
, "special:aah") ) {
17834 rawsize
= ahh_size
; rawdata
= ahh_data
;
17836 else if( strstr(fileName
, "special:britestk") ) {
17837 rawsize
= britestk_size
; rawdata
= britestk_data
;
17839 else if( strstr(fileName
, "special:dope") ) {
17840 rawsize
= dope_size
; rawdata
= dope_data
;
17842 else if( strstr(fileName
, "special:eee") ) {
17843 rawsize
= eee_size
; rawdata
= eee_data
;
17845 else if( strstr(fileName
, "special:fwavblnk") ) {
17846 rawsize
= fwavblnk_size
; rawdata
= fwavblnk_data
;
17848 else if( strstr(fileName
, "special:halfwave") ) {
17849 rawsize
= halfwave_size
; rawdata
= halfwave_data
;
17851 else if( strstr(fileName
, "special:impuls10") ) {
17852 rawsize
= impuls10_size
; rawdata
= impuls10_data
;
17854 else if( strstr(fileName
, "special:impuls20") ) {
17855 rawsize
= impuls20_size
; rawdata
= impuls20_data
;
17857 else if( strstr(fileName
, "special:impuls40") ) {
17858 rawsize
= impuls40_size
; rawdata
= impuls40_data
;
17860 else if( strstr(fileName
, "special:mand1") ) {
17861 rawsize
= mand1_size
; rawdata
= mand1_data
;
17863 else if( strstr(fileName
, "special:mandpluk") ) {
17864 rawsize
= mandpluk_size
; rawdata
= mandpluk_data
;
17866 else if( strstr(fileName
, "special:marmstk1") ) {
17867 rawsize
= marmstk1_size
; rawdata
= marmstk1_data
;
17869 else if( strstr(fileName
, "special:ooo") ) {
17870 rawsize
= ooo_size
; rawdata
= ooo_data
;
17872 else if( strstr(fileName
, "special:peksblnk") ) {
17873 rawsize
= peksblnk_size
; rawdata
= peksblnk_data
;
17875 else if( strstr(fileName
, "special:ppksblnk") ) {
17876 rawsize
= ppksblnk_size
; rawdata
= ppksblnk_data
;
17878 else if( strstr(fileName
, "special:silence") ) {
17879 rawsize
= silence_size
; rawdata
= silence_data
;
17881 else if( strstr(fileName
, "special:sineblnk") ) {
17882 rawsize
= sineblnk_size
; rawdata
= sineblnk_data
;
17884 else if( strstr(fileName
, "special:sinewave") ) {
17885 rawsize
= sinewave_size
; rawdata
= sinewave_data
;
17887 else if( strstr(fileName
, "special:snglpeak") ) {
17888 rawsize
= snglpeak_size
; rawdata
= snglpeak_data
;
17890 else if( strstr(fileName
, "special:twopeaks") ) {
17891 rawsize
= twopeaks_size
; rawdata
= twopeaks_data
;
17893 else if( strstr(fileName
, "special:glot_pop") ) {
17894 rawsize
= glot_pop_size
; rawdata
= glot_pop_data
;
17895 fileRate
= 44100.0; rate
= (MY_FLOAT
)44100.0 / Stk::sampleRate();
17897 else if( strstr(fileName
, "special:glot_ahh") ) {
17898 rawsize
= glot_ahh_size
; rawdata
= glot_ahh_data
;
17899 fileRate
= 44100.0; rate
= (MY_FLOAT
)44100.0 / Stk::sampleRate();
17901 else if( strstr(fileName
, "special:glot_eee" ) ) {
17902 rawsize
= glot_eee_size
; rawdata
= glot_eee_data
;
17903 fileRate
= 44100.0; rate
= (MY_FLOAT
)44100.0 / Stk::sampleRate();
17905 else if( strstr(fileName
, "special:glot_ooo" ) ) {
17906 rawsize
= glot_ooo_size
; rawdata
= glot_ooo_data
;
17907 fileRate
= 44100.0; rate
= (MY_FLOAT
)44100.0 / Stk::sampleRate();
17911 if ( data
) delete [] data
;
17912 data
= (MY_FLOAT
*) new MY_FLOAT
[rawsize
+1];
17913 bufferSize
= rawsize
;
17914 fileSize
= bufferSize
;
17915 for ( int j
=0; j
< rawsize
; j
++ ) {
17916 data
[j
] = (MY_FLOAT
) rawdata
[j
];
17922 data
[bufferSize
] = data
[0];
17924 else readData( 0 ); // Load file data.
17926 if ( doNormalize
) normalize();
17929 interpolate
= ( fmod( rate
, 1.0 ) != 0.0 );
17933 sprintf(msg
, "[chuck](via WvIn): Error reading file (%s).", fileName
);
17934 handleError(msg
, StkError::FILE_ERROR
);
17937 bool WvIn :: getRawInfo( const char *fileName
)
17939 // Use the system call "stat" to determine the file length.
17940 struct stat filestat
;
17941 if ( stat(fileName
, &filestat
) == -1 ) {
17942 sprintf(msg
, "[chuck](via WvIn): Could not stat RAW file (%s).", fileName
);
17946 fileSize
= (long) filestat
.st_size
/ 2; // length in 2-byte samples
17947 bufferSize
= fileSize
;
17948 if (fileSize
> CHUNK_THRESHOLD
) {
17950 bufferSize
= CHUNK_SIZE
;
17951 gain
= 1.0 / 32768.0;
17954 // STK rawwave files have no header and are assumed to contain a
17955 // monophonic stream of 16-bit signed integers in big-endian byte
17956 // order with a sample rate of 22050 Hz.
17959 rate
= (MY_FLOAT
) 22050.0 / Stk::sampleRate();
17960 fileRate
= 22050.0;
17961 interpolate
= false;
17962 dataType
= STK_SINT16
;
17964 if( little_endian
)
17970 bool WvIn :: getWavInfo( const char *fileName
)
17972 // Find "format" chunk ... it must come before the "data" chunk.
17975 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
17976 while ( strncmp(id
, "fmt ", 4) ) {
17977 if ( fread(&chunkSize
, 4, 1, fd
) != 1 ) goto error
;
17978 if( !little_endian
)
17979 swap32((unsigned char *)&chunkSize
);
17981 if ( fseek(fd
, chunkSize
, SEEK_CUR
) == -1 ) goto error
;
17982 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
17985 // Check that the data is not compressed.
17987 if ( fread(&chunkSize
, 4, 1, fd
) != 1 ) goto error
; // Read fmt chunk size.
17988 if ( fread(&format_tag
, 2, 1, fd
) != 1 ) goto error
;
17989 if( !little_endian
)
17991 swap16((unsigned char *)&format_tag
);
17992 swap32((unsigned char *)&chunkSize
);
17994 if (format_tag
!= 1 && format_tag
!= 3 ) { // PCM = 1, FLOAT = 3
17995 sprintf(msg
, "[chuck](via WvIn): %s contains an unsupported data format type (%d).", fileName
, format_tag
);
17999 // Get number of channels from the header.
18001 if ( fread(&temp
, 2, 1, fd
) != 1 ) goto error
;
18002 if( !little_endian
)
18003 swap16((unsigned char *)&temp
);
18005 channels
= (unsigned int ) temp
;
18007 // Get file sample rate from the header.
18009 if ( fread(&srate
, 4, 1, fd
) != 1 ) goto error
;
18010 if( !little_endian
)
18011 swap32((unsigned char *)&srate
);
18013 fileRate
= (MY_FLOAT
) srate
;
18015 // Set default rate based on file sampling rate.
18016 rate
= (MY_FLOAT
) ( srate
/ Stk::sampleRate() );
18018 // Determine the data type.
18020 if ( fseek(fd
, 6, SEEK_CUR
) == -1 ) goto error
; // Locate bits_per_sample info.
18021 if ( fread(&temp
, 2, 1, fd
) != 1 ) goto error
;
18022 if( !little_endian
)
18023 swap16((unsigned char *)&temp
);
18025 if ( format_tag
== 1 ) {
18027 dataType
= STK_SINT8
;
18028 else if (temp
== 16)
18029 dataType
= STK_SINT16
;
18030 else if (temp
== 32)
18031 dataType
= STK_SINT32
;
18033 else if ( format_tag
== 3 ) {
18035 dataType
= MY_FLOAT32
;
18036 else if (temp
== 64)
18037 dataType
= MY_FLOAT64
;
18039 if ( dataType
== 0 ) {
18040 sprintf(msg
, "[chuck](via WvIn): %d bits per sample with data format %d are not supported (%s).", temp
, format_tag
, fileName
);
18044 // Jump over any remaining part of the "fmt" chunk.
18045 if ( fseek(fd
, chunkSize
-16, SEEK_CUR
) == -1 ) goto error
;
18047 // Find "data" chunk ... it must come after the "fmt" chunk.
18048 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
18050 while ( strncmp(id
, "data", 4) ) {
18051 if ( fread(&chunkSize
, 4, 1, fd
) != 1 ) goto error
;
18052 if( !little_endian
)
18053 swap32((unsigned char *)&chunkSize
);
18055 if ( fseek(fd
, chunkSize
, SEEK_CUR
) == -1 ) goto error
;
18056 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
18059 // Get length of data from the header.
18061 if ( fread(&bytes
, 4, 1, fd
) != 1 ) goto error
;
18062 if( !little_endian
)
18063 swap32((unsigned char *)&bytes
);
18065 fileSize
= 8 * bytes
/ temp
/ channels
; // sample frames
18066 bufferSize
= fileSize
;
18067 if (fileSize
> CHUNK_THRESHOLD
) {
18069 bufferSize
= CHUNK_SIZE
;
18072 dataOffset
= ftell(fd
);
18074 if( !little_endian
)
18080 sprintf(msg
, "[chuck](via WvIn): Error reading WAV file (%s).", fileName
);
18084 bool WvIn :: getSndInfo( const char *fileName
)
18086 // Determine the data type.
18088 if ( fseek(fd
, 12, SEEK_SET
) == -1 ) goto error
; // Locate format
18089 if ( fread(&format
, 4, 1, fd
) != 1 ) goto error
;
18090 if( little_endian
)
18091 swap32((unsigned char *)&format
);
18093 if (format
== 2) dataType
= STK_SINT8
;
18094 else if (format
== 3) dataType
= STK_SINT16
;
18095 else if (format
== 5) dataType
= STK_SINT32
;
18096 else if (format
== 6) dataType
= MY_FLOAT32
;
18097 else if (format
== 7) dataType
= MY_FLOAT64
;
18099 sprintf(msg
, "[chuck](via WvIn): data format in file %s is not supported.", fileName
);
18103 // Get file sample rate from the header.
18105 if ( fread(&srate
, 4, 1, fd
) != 1 ) goto error
;
18106 if( little_endian
)
18107 swap32((unsigned char *)&srate
);
18109 fileRate
= (MY_FLOAT
) srate
;
18111 // Set default rate based on file sampling rate.
18112 rate
= (MY_FLOAT
) ( srate
/ sampleRate() );
18114 // Get number of channels from the header.
18116 if ( fread(&chans
, 4, 1, fd
) != 1 ) goto error
;
18117 if( little_endian
)
18118 swap32((unsigned char *)&chans
);
18122 if ( fseek(fd
, 4, SEEK_SET
) == -1 ) goto error
;
18123 if ( fread(&dataOffset
, 4, 1, fd
) != 1 ) goto error
;
18124 if( little_endian
)
18125 swap32((unsigned char *)&dataOffset
);
18127 // Get length of data from the header.
18128 if ( fread(&fileSize
, 4, 1, fd
) != 1 ) goto error
;
18129 if( little_endian
)
18130 swap32((unsigned char *)&fileSize
);
18132 fileSize
/= 2 * channels
; // Convert to sample frames.
18133 bufferSize
= fileSize
;
18134 if (fileSize
> CHUNK_THRESHOLD
) {
18136 bufferSize
= CHUNK_SIZE
;
18140 if( little_endian
)
18146 sprintf(msg
, "[chuck](via WvIn): Error reading SND file (%s).", fileName
);
18150 bool WvIn :: getAifInfo( const char *fileName
)
18155 // Determine whether this is AIFF or AIFC.
18156 if ( fseek(fd
, 8, SEEK_SET
) == -1 ) goto error
;
18157 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
18158 if ( !strncmp(id
, "AIFC", 4) ) aifc
= true;
18160 // Find "common" chunk
18162 if ( fread(&id
, 4, 1, fd
) != 1) goto error
;
18163 while ( strncmp(id
, "COMM", 4) ) {
18164 if ( fread(&chunkSize
, 4, 1, fd
) != 1 ) goto error
;
18165 if( little_endian
)
18166 swap32((unsigned char *)&chunkSize
);
18168 if ( fseek(fd
, chunkSize
, SEEK_CUR
) == -1 ) goto error
;
18169 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
18172 // Get number of channels from the header.
18174 if ( fseek(fd
, 4, SEEK_CUR
) == -1 ) goto error
; // Jump over chunk size
18175 if ( fread(&temp
, 2, 1, fd
) != 1 ) goto error
;
18176 if( little_endian
)
18177 swap16((unsigned char *)&temp
);
18181 // Get length of data from the header.
18183 if ( fread(&frames
, 4, 1, fd
) != 1 ) goto error
;
18184 if( little_endian
)
18185 swap32((unsigned char *)&frames
);
18187 fileSize
= frames
; // sample frames
18188 bufferSize
= fileSize
;
18189 if (fileSize
> CHUNK_THRESHOLD
) {
18191 bufferSize
= CHUNK_SIZE
;
18194 // Read the number of bits per sample.
18195 if ( fread(&temp
, 2, 1, fd
) != 1 ) goto error
;
18196 if( little_endian
)
18197 swap16((unsigned char *)&temp
);
18199 // Get file sample rate from the header. For AIFF files, this value
18200 // is stored in a 10-byte, IEEE Standard 754 floating point number,
18201 // so we need to convert it first.
18202 unsigned char srate
[10];
18204 unsigned long mantissa
;
18205 unsigned long last
;
18206 if ( fread(&srate
, 10, 1, fd
) != 1 ) goto error
;
18207 mantissa
= (unsigned long) *(unsigned long *)(srate
+2);
18208 if( little_endian
)
18209 swap32((unsigned char *)&mantissa
);
18211 exp
= 30 - *(srate
+1);
18217 if (last
& 0x00000001) mantissa
++;
18218 fileRate
= (MY_FLOAT
) mantissa
;
18220 // Set default rate based on file sampling rate.
18221 rate
= (MY_FLOAT
) ( fileRate
/ sampleRate() );
18223 // Determine the data format.
18225 if ( aifc
== false ) {
18226 if ( temp
== 8 ) dataType
= STK_SINT8
;
18227 else if ( temp
== 16 ) dataType
= STK_SINT16
;
18228 else if ( temp
== 32 ) dataType
= STK_SINT32
;
18231 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
18232 if ( (!strncmp(id
, "fl32", 4) || !strncmp(id
, "FL32", 4)) && temp
== 32 ) dataType
= MY_FLOAT32
;
18233 else if ( (!strncmp(id
, "fl64", 4) || !strncmp(id
, "FL64", 4)) && temp
== 64 ) dataType
= MY_FLOAT64
;
18235 if ( dataType
== 0 ) {
18236 sprintf(msg
, "[chuck](via WvIn): %d bits per sample in file %s are not supported.", temp
, fileName
);
18240 // Start at top to find data (SSND) chunk ... chunk order is undefined.
18241 if ( fseek(fd
, 12, SEEK_SET
) == -1 ) goto error
;
18243 // Find data (SSND) chunk
18244 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
18245 while ( strncmp(id
, "SSND", 4) ) {
18246 if ( fread(&chunkSize
, 4, 1, fd
) != 1 ) goto error
;
18247 if( little_endian
)
18248 swap32((unsigned char *)&chunkSize
);
18250 if ( fseek(fd
, chunkSize
, SEEK_CUR
) == -1 ) goto error
;
18251 if ( fread(&id
, 4, 1, fd
) != 1 ) goto error
;
18254 // Skip over chunk size, offset, and blocksize fields
18255 if ( fseek(fd
, 12, SEEK_CUR
) == -1 ) goto error
;
18257 dataOffset
= ftell(fd
);
18259 if( little_endian
)
18265 sprintf(msg
, "[chuck](via WvIn): Error reading AIFF file (%s).", fileName
);
18269 bool WvIn :: getMatInfo( const char *fileName
)
18271 // Verify this is a version 5 MAT-file format.
18273 if ( fseek(fd
, 0, SEEK_SET
) == -1 ) goto error
;
18274 if ( fread(&head
, 4, 1, fd
) != 1 ) goto error
;
18275 // If any of the first 4 characters of the header = 0, then this is
18276 // a Version 4 MAT-file.
18277 if ( strstr(head
, "0") ) {
18278 sprintf(msg
, "[chuck](via WvIn): %s appears to be a Version 4 MAT-file, which is not currently supported.",
18283 // Determine the endian-ness of the file.
18286 // Locate "M" and "I" characters in header.
18287 if ( fseek(fd
, 126, SEEK_SET
) == -1 ) goto error
;
18288 if ( fread(&mi
, 2, 1, fd
) != 1) goto error
;
18289 if( little_endian
)
18291 if ( !strncmp(mi
, "MI", 2) )
18293 else if ( strncmp(mi
, "IM", 2) ) goto error
;
18297 if ( !strncmp(mi
, "IM", 2))
18299 else if ( strncmp(mi
, "MI", 2) ) goto error
;
18302 // Check the data element type
18304 if ( fread(&datatype
, 4, 1, fd
) != 1 ) goto error
;
18305 if ( byteswap
) swap32((unsigned char *)&datatype
);
18306 if (datatype
!= 14) {
18307 sprintf(msg
, "[chuck](via WvIn): The file does not contain a single Matlab array (or matrix) data element.");
18311 // Determine the array data type.
18314 if ( fseek(fd
, 168, SEEK_SET
) == -1 ) goto error
;
18315 if ( fread(&tmp
, 4, 1, fd
) != 1 ) goto error
;
18316 if (byteswap
) swap32((unsigned char *)&tmp
);
18317 if (tmp
== 1) { // array name > 4 characters
18318 if ( fread(&tmp
, 4, 1, fd
) != 1 ) goto error
; // get array name length
18319 if (byteswap
) swap32((unsigned char *)&tmp
);
18320 size
= (SINT32
) ceil((float)tmp
/ 8);
18321 if ( fseek(fd
, size
*8, SEEK_CUR
) == -1 ) goto error
; // jump over array name
18323 else { // array name <= 4 characters, compressed data element
18324 if ( fseek(fd
, 4, SEEK_CUR
) == -1 ) goto error
;
18326 if ( fread(&tmp
, 4, 1, fd
) != 1 ) goto error
;
18327 if (byteswap
) swap32((unsigned char *)&tmp
);
18328 if ( tmp
== 1 ) dataType
= STK_SINT8
;
18329 else if ( tmp
== 3 ) dataType
= STK_SINT16
;
18330 else if ( tmp
== 5 ) dataType
= STK_SINT32
;
18331 else if ( tmp
== 7 ) dataType
= MY_FLOAT32
;
18332 else if ( tmp
== 9 ) dataType
= MY_FLOAT64
;
18334 sprintf(msg
, "[chuck](via WvIn): The MAT-file array data format (%d) is not supported.", tmp
);
18338 // Get number of rows from the header.
18340 if ( fseek(fd
, 160, SEEK_SET
) == -1 ) goto error
;
18341 if ( fread(&rows
, 4, 1, fd
) != 1 ) goto error
;
18342 if (byteswap
) swap32((unsigned char *)&rows
);
18344 // Get number of columns from the header.
18346 if ( fread(&columns
,4, 1, fd
) != 1 ) goto error
;
18347 if (byteswap
) swap32((unsigned char *)&columns
);
18349 // Assume channels = smaller of rows or columns.
18350 if (rows
< columns
) {
18352 fileSize
= columns
;
18355 sprintf(msg
, "[chuck](via WvIn): Transpose the MAT-file array so that audio channels fill matrix rows (not columns).");
18358 bufferSize
= fileSize
;
18359 if (fileSize
> CHUNK_THRESHOLD
) {
18361 bufferSize
= CHUNK_SIZE
;
18364 // Move read pointer to the data in the file.
18366 if ( fseek(fd
, 132, SEEK_SET
) == -1 ) goto error
;
18367 if ( fread(&headsize
, 4, 1, fd
) != 1 ) goto error
; // file size from 132nd byte
18368 if (byteswap
) swap32((unsigned char *)&headsize
);
18369 headsize
-= fileSize
* 8 * channels
;
18370 if ( fseek(fd
, headsize
, SEEK_CUR
) == -1 ) goto error
;
18371 dataOffset
= ftell(fd
);
18373 // Assume MAT-files have 44100 Hz sample rate.
18374 fileRate
= 44100.0;
18376 // Set default rate based on file sampling rate.
18377 rate
= (MY_FLOAT
) ( fileRate
/ sampleRate() );
18382 sprintf(msg
, "[chuck](via WvIn): Error reading MAT-file (%s).", fileName
);
18390 void WvIn :: readData( unsigned long index
)
18392 while (index
< (unsigned long)chunkPointer
) {
18394 chunkPointer
-= CHUNK_SIZE
;
18395 bufferSize
= CHUNK_SIZE
;
18396 if (chunkPointer
< 0) {
18397 bufferSize
+= chunkPointer
;
18401 while (index
>= chunkPointer
+bufferSize
) {
18403 chunkPointer
+= CHUNK_SIZE
;
18404 bufferSize
= CHUNK_SIZE
;
18405 if ( (unsigned long)chunkPointer
+CHUNK_SIZE
>= fileSize
) {
18406 bufferSize
= fileSize
- chunkPointer
;
18410 long i
, length
= bufferSize
;
18411 bool endfile
= (chunkPointer
+bufferSize
== fileSize
);
18412 if ( !endfile
) length
+= 1;
18414 // Read samples into data[]. Use MY_FLOAT data structure
18415 // to store samples.
18416 if ( dataType
== STK_SINT16
) {
18417 SINT16
*buf
= (SINT16
*)data
;
18418 if (fseek(fd
, dataOffset
+(long)(chunkPointer
*channels
*2), SEEK_SET
) == -1) goto error
;
18419 if (fread(buf
, length
*channels
, 2, fd
) != 2 ) goto error
;
18422 for (i
=length
*channels
-1; i
>=0; i
--)
18423 swap16((unsigned char *)(ptr
++));
18425 for (i
=length
*channels
-1; i
>=0; i
--)
18428 else if ( dataType
== STK_SINT32
) {
18429 SINT32
*buf
= (SINT32
*)data
;
18430 if (fseek(fd
, dataOffset
+(long)(chunkPointer
*channels
*4), SEEK_SET
) == -1) goto error
;
18431 if (fread(buf
, length
*channels
, 4, fd
) != 4 ) goto error
;
18434 for (i
=length
*channels
-1; i
>=0; i
--)
18435 swap32((unsigned char *)(ptr
++));
18437 for (i
=length
*channels
-1; i
>=0; i
--)
18440 else if ( dataType
== MY_FLOAT32
) {
18441 FLOAT32
*buf
= (FLOAT32
*)data
;
18442 if (fseek(fd
, dataOffset
+(long)(chunkPointer
*channels
*4), SEEK_SET
) == -1) goto error
;
18443 if (fread(buf
, length
*channels
, 4, fd
) != 4 ) goto error
;
18445 FLOAT32
*ptr
= buf
;
18446 for (i
=length
*channels
-1; i
>=0; i
--)
18447 swap32((unsigned char *)(ptr
++));
18449 for (i
=length
*channels
-1; i
>=0; i
--)
18452 else if ( dataType
== MY_FLOAT64
) {
18453 FLOAT64
*buf
= (FLOAT64
*)data
;
18454 if (fseek(fd
, dataOffset
+(long)(chunkPointer
*channels
*8), SEEK_SET
) == -1) goto error
;
18455 if (fread(buf
, length
*channels
, 8, fd
) != 8 ) goto error
;
18457 FLOAT64
*ptr
= buf
;
18458 for (i
=length
*channels
-1; i
>=0; i
--)
18459 swap64((unsigned char *)(ptr
++));
18461 for (i
=length
*channels
-1; i
>=0; i
--)
18464 else if ( dataType
== STK_SINT8
) {
18465 unsigned char *buf
= (unsigned char *)data
;
18466 if (fseek(fd
, dataOffset
+(long)(chunkPointer
*channels
), SEEK_SET
) == -1) goto error
;
18467 if (fread(buf
, length
*channels
, 1, fd
) != 1 ) goto error
;
18468 for (i
=length
*channels
-1; i
>=0; i
--)
18469 data
[i
] = buf
[i
] - 128.0; // 8-bit WAV data is unsigned!
18472 // If at end of file, repeat last sample frame for interpolation.
18474 for (unsigned int j
=0; j
<channels
; j
++)
18475 data
[bufferSize
*channels
+j
] = data
[(bufferSize
-1)*channels
+j
];
18486 sprintf(msg
, "[chuck](via WvIn): Error reading file data.");
18487 handleError(msg
, StkError::FILE_ERROR
);
18490 void WvIn :: reset(void)
18492 time
= (MY_FLOAT
) 0.0;
18493 for (unsigned int i
=0; i
<channels
; i
++)
18494 lastOutput
[i
] = (MY_FLOAT
) 0.0;
18498 void WvIn :: normalize(void)
18500 this->normalize((MY_FLOAT
) 1.0);
18503 // Normalize all channels equally by the greatest magnitude in all of the data.
18504 void WvIn :: normalize(MY_FLOAT peak
)
18507 if ( dataType
== STK_SINT8
) gain
= peak
/ 128.0;
18508 else if ( dataType
== STK_SINT16
) gain
= peak
/ 32768.0;
18509 else if ( dataType
== STK_SINT32
) gain
= peak
/ 2147483648.0;
18510 else if ( dataType
== MY_FLOAT32
|| dataType
== MY_FLOAT64
) gain
= peak
;
18516 MY_FLOAT max
= (MY_FLOAT
) 0.0;
18518 for (i
=0; i
<channels
*bufferSize
; i
++) {
18519 if (fabs(data
[i
]) > max
)
18520 max
= (MY_FLOAT
) fabs((double) data
[i
]);
18524 max
= (MY_FLOAT
) 1.0 / max
;
18526 for (i
=0;i
<=channels
*bufferSize
;i
++)
18531 unsigned long WvIn :: getSize(void) const
18536 unsigned int WvIn :: getChannels(void) const
18541 MY_FLOAT
WvIn :: getFileRate(void) const
18546 bool WvIn :: isFinished(void) const
18551 void WvIn :: setRate(MY_FLOAT aRate
)
18555 // If negative rate and at beginning of sound, move pointer to end
18557 if ( (rate
< 0) && (time
== 0.0) ) time
+= rate
+ fileSize
;
18559 if (fmod(rate
, 1.0) != 0.0) interpolate
= true;
18560 else interpolate
= false;
18563 void WvIn :: addTime(MY_FLOAT aTime
)
18565 // Add an absolute time in samples
18568 if (time
< 0.0) time
= 0.0;
18569 if (time
>= fileSize
) {
18575 void WvIn :: setInterpolate(bool doInterpolate
)
18577 interpolate
= doInterpolate
;
18580 const MY_FLOAT
*WvIn :: lastFrame(void) const
18585 MY_FLOAT
WvIn :: lastOut(void) const
18587 if ( channels
== 1 )
18588 return *lastOutput
;
18590 MY_FLOAT output
= 0.0;
18591 for (unsigned int i
=0; i
<channels
; i
++ ) {
18592 output
+= lastOutput
[i
];
18594 return output
/ channels
;
18597 MY_FLOAT
WvIn :: tick(void)
18603 MY_FLOAT
*WvIn :: tick(MY_FLOAT
*vector
, unsigned int vectorSize
)
18605 for ( unsigned int i
=0; i
<vectorSize
; i
++ )
18606 vector
[i
] = tick();
18611 const MY_FLOAT
*WvIn :: tickFrame(void)
18613 register MY_FLOAT tyme
, alpha
;
18614 register unsigned long i
, index
;
18616 if (finished
) return lastOutput
;
18620 // Check the time address vs. our current buffer limits.
18621 if ( (tyme
< chunkPointer
) || (tyme
>= chunkPointer
+bufferSize
) )
18622 this->readData((long) tyme
);
18623 // Adjust index for the current buffer.
18624 tyme
-= chunkPointer
;
18627 // Integer part of time address.
18628 index
= (long) tyme
;
18631 // Linear interpolation ... fractional part of time address.
18632 alpha
= tyme
- (MY_FLOAT
) index
;
18634 for (i
=0; i
<channels
; i
++) {
18635 lastOutput
[i
] = data
[index
];
18636 lastOutput
[i
] += (alpha
* (data
[index
+channels
] - lastOutput
[i
]));
18642 for (i
=0; i
<channels
; i
++)
18643 lastOutput
[i
] = data
[index
++];
18647 // Scale outputs by gain.
18648 for (i
=0; i
<channels
; i
++) lastOutput
[i
] *= gain
;
18651 // Increment time, which can be negative.
18653 if ( time
< 0.0 || time
>= fileSize
) finished
= true;
18658 MY_FLOAT
*WvIn :: tickFrame(MY_FLOAT
*frameVector
, unsigned int frames
)
18661 for ( unsigned int i
=0; i
<frames
; i
++ ) {
18663 for ( j
=0; j
<channels
; j
++ )
18664 frameVector
[i
*channels
+j
] = lastOutput
[j
];
18667 return frameVector
;
18669 /***************************************************/
18671 \brief STK audio data output base class.
18673 This class provides output support for various
18674 audio file formats. It also serves as a base
18675 class for "realtime" streaming subclasses.
18677 WvOut writes samples to an audio file. It
18678 supports multi-channel data in interleaved
18679 format. It is important to distinguish the
18680 tick() methods, which output single samples
18681 to all channels in a sample frame, from the
18682 tickFrame() method, which takes a pointer
18683 to multi-channel sample frame data.
18685 WvOut currently supports WAV, AIFF, AIFC, SND
18686 (AU), MAT-file (Matlab), and STK RAW file
18687 formats. Signed integer (8-, 16-, and 32-bit)
18688 and floating- point (32- and 64-bit) data types
18689 are supported. STK RAW files use 16-bit
18690 integers by definition. MAT-files will always
18691 be written as 64-bit floats. If a data type
18692 specification does not match the specified file
18693 type, the data type will automatically be
18694 modified. Uncompressed data types are not
18697 Currently, WvOut is non-interpolating and the
18698 output rate is always Stk::sampleRate().
18700 by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
18702 /***************************************************/
18705 const WvOut::FILE_TYPE
WvOut :: WVOUT_RAW
= 1;
18706 const WvOut::FILE_TYPE
WvOut :: WVOUT_WAV
= 2;
18707 const WvOut::FILE_TYPE
WvOut :: WVOUT_SND
= 3;
18708 const WvOut::FILE_TYPE
WvOut :: WVOUT_AIF
= 4;
18709 const WvOut::FILE_TYPE
WvOut :: WVOUT_MAT
= 5;
18711 // WAV header structure. See ftp://ftp.isi.edu/in-notes/rfc2361.txt
18712 // for information regarding format codes.
18714 char riff
[4]; // "RIFF"
18715 SINT32 file_size
; // in bytes
18716 char wave
[4]; // "WAVE"
18717 char fmt
[4]; // "fmt "
18718 SINT32 chunk_size
; // in bytes (16 for PCM)
18719 SINT16 format_tag
; // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
18720 SINT16 num_chans
; // 1=mono, 2=stereo
18721 SINT32 sample_rate
;
18722 SINT32 bytes_per_sec
;
18723 SINT16 bytes_per_samp
; // 2=16-bit mono, 4=16-bit stereo
18724 SINT16 bits_per_samp
;
18725 char data
[4]; // "data"
18726 SINT32 data_length
; // in bytes
18729 // SND (AU) header structure (NeXT and Sun).
18733 SINT32 data_length
;
18735 SINT32 sample_rate
;
18736 SINT32 num_channels
;
18740 // AIFF/AIFC header structure ... only the part common to both
18743 char form
[4]; // "FORM"
18744 SINT32 form_size
; // in bytes
18745 char aiff
[4]; // "AIFF" or "AIFC"
18746 char comm
[4]; // "COMM"
18747 SINT32 comm_size
; // "COMM" chunk size (18 for AIFF, 24 for AIFC)
18748 SINT16 num_chans
; // number of channels
18749 unsigned long sample_frames
; // sample frames of audio data
18750 SINT16 sample_size
; // in bits
18751 unsigned char srate
[10]; // IEEE 754 floating point format
18755 char ssnd
[4]; // "SSND"
18756 SINT32 ssnd_size
; // "SSND" chunk size
18757 unsigned long offset
; // data offset in data block (should be 0)
18758 unsigned long block_size
; // not used by STK (should be 0)
18761 // MAT-file 5 header structure.
18763 char heading
[124]; // Header text field
18764 SINT16 hff
[2]; // Header flag fields
18765 SINT32 adf
[11]; // Array data format fields
18766 // There's more, but it's of variable length
18774 WvOut::WvOut( const char *fileName
, unsigned int nChannels
, FILE_TYPE type
, Stk::STK_FORMAT format
)
18777 openFile( fileName
, nChannels
, type
, format
);
18788 void WvOut :: init()
18797 m_filename
[0] = '\0';
18802 void WvOut :: closeFile( void )
18805 // If there's an existing file, close it first.
18806 writeData( counter
);
18808 if ( fileType
== WVOUT_RAW
)
18810 else if ( fileType
== WVOUT_WAV
)
18812 else if ( fileType
== WVOUT_SND
)
18814 else if ( fileType
== WVOUT_AIF
)
18816 else if ( fileType
== WVOUT_MAT
)
18820 // printf("%f Seconds Computed\n\n", getTime() );
18824 m_filename
[0] = '\0';
18828 void WvOut :: openFile( const char *fileName
, unsigned int nChannels
, WvOut::FILE_TYPE type
, Stk::STK_FORMAT format
)
18831 strncpy( m_filename
, fileName
, 255);
18832 if ( strlen( fileName
) > 255 )
18833 m_filename
[255] = '\0';
18835 if ( nChannels
< 1 ) {
18836 sprintf(msg
, "[chuck](via WvOut): the channels argument must be greater than zero!");
18837 handleError( msg
, StkError::FUNCTION_ARGUMENT
);
18840 unsigned int lastChannels
= channels
;
18841 channels
= nChannels
;
18844 if ( format
!= STK_SINT8
&& format
!= STK_SINT16
&&
18845 format
!= STK_SINT32
&& format
!= MY_FLOAT32
&&
18846 format
!= MY_FLOAT64
) {
18847 sprintf( msg
, "[chuck](via WvOut): Unknown data type specified (%ld).", format
);
18848 handleError(msg
, StkError::FUNCTION_ARGUMENT
);
18852 bool result
= false;
18853 if ( fileType
== WVOUT_RAW
) {
18854 if ( channels
!= 1 ) {
18855 sprintf(msg
, "[chuck](via WvOut): STK RAW files are, by definition, always monaural (channels = %d not supported)!", nChannels
);
18856 handleError( msg
, StkError::FUNCTION_ARGUMENT
);
18858 result
= setRawFile( fileName
);
18860 else if ( fileType
== WVOUT_WAV
)
18861 result
= setWavFile( fileName
);
18862 else if ( fileType
== WVOUT_SND
)
18863 result
= setSndFile( fileName
);
18864 else if ( fileType
== WVOUT_AIF
)
18865 result
= setAifFile( fileName
);
18866 else if ( fileType
== WVOUT_MAT
)
18867 result
= setMatFile( fileName
);
18869 sprintf(msg
, "[chuck](via WvOut): Unknown file type specified (%ld).", fileType
);
18870 handleError(msg
, StkError::FUNCTION_ARGUMENT
);
18873 if ( result
== false )
18874 handleError(msg
, StkError::FILE_ERROR
);
18876 // Allocate new memory if necessary.
18877 if ( lastChannels
< channels
) {
18878 if ( data
) delete [] data
;
18879 data
= (MY_FLOAT
*) new MY_FLOAT
[BUFFER_SIZE
*channels
];
18884 bool WvOut :: setRawFile( const char *fileName
)
18887 strncpy(name
, fileName
, 128);
18888 if ( strstr(name
, ".raw") == NULL
) strcat(name
, ".raw");
18889 fd
= fopen(name
, "wb");
18891 sprintf(msg
, "[chuck](via WvOut): Could not create RAW file: %s", name
);
18895 if ( dataType
!= STK_SINT16
) {
18896 dataType
= STK_SINT16
;
18897 sprintf(msg
, "[chuck](via WvOut): Using 16-bit signed integer data format for file %s.", name
);
18898 handleError(msg
, StkError::WARNING
);
18902 if( little_endian
)
18905 // printf("\nCreating RAW file: %s\n", name);
18909 bool WvOut :: setWavFile( const char *fileName
)
18912 strncpy(name
, fileName
, 128);
18913 if ( strstr(name
, ".wav") == NULL
) strcat(name
, ".wav");
18914 fd
= fopen(name
, "wb");
18916 sprintf(msg
, "[chuck](via WvOut): Could not create WAV file: %s", name
);
18920 struct wavhdr hdr
= {"RIF", 44, "WAV", "fmt", 16, 1, 1,
18921 (SINT32
) Stk::sampleRate(), 0, 2, 16, "dat", 0};
18926 hdr
.num_chans
= (SINT16
) channels
;
18927 if ( dataType
== STK_SINT8
)
18928 hdr
.bits_per_samp
= 8;
18929 else if ( dataType
== STK_SINT16
)
18930 hdr
.bits_per_samp
= 16;
18931 else if ( dataType
== STK_SINT32
)
18932 hdr
.bits_per_samp
= 32;
18933 else if ( dataType
== MY_FLOAT32
) {
18934 hdr
.format_tag
= 3;
18935 hdr
.bits_per_samp
= 32;
18937 else if ( dataType
== MY_FLOAT64
) {
18938 hdr
.format_tag
= 3;
18939 hdr
.bits_per_samp
= 64;
18941 hdr
.bytes_per_samp
= (SINT16
) (channels
* hdr
.bits_per_samp
/ 8);
18942 hdr
.bytes_per_sec
= (SINT32
) (hdr
.sample_rate
* hdr
.bytes_per_samp
);
18945 if( !little_endian
)
18948 swap32((unsigned char *)&hdr
.file_size
);
18949 swap32((unsigned char *)&hdr
.chunk_size
);
18950 swap16((unsigned char *)&hdr
.format_tag
);
18951 swap16((unsigned char *)&hdr
.num_chans
);
18952 swap32((unsigned char *)&hdr
.sample_rate
);
18953 swap32((unsigned char *)&hdr
.bytes_per_sec
);
18954 swap16((unsigned char *)&hdr
.bytes_per_samp
);
18955 swap16((unsigned char *)&hdr
.bits_per_samp
);
18958 if ( fwrite(&hdr
, 4, 11, fd
) != 11 ) {
18959 sprintf(msg
, "[chuck](via WvOut): Could not write WAV header for file %s", name
);
18963 // printf("\nCreating WAV file: %s\n", name);
18967 void WvOut :: closeWavFile( void )
18969 int bytes_per_sample
= 1;
18970 if ( dataType
== STK_SINT16
)
18971 bytes_per_sample
= 2;
18972 else if ( dataType
== STK_SINT32
|| dataType
== MY_FLOAT32
)
18973 bytes_per_sample
= 4;
18974 else if ( dataType
== MY_FLOAT64
)
18975 bytes_per_sample
= 8;
18977 SINT32 bytes
= totalCount
* channels
* bytes_per_sample
;
18978 if( !little_endian
)
18979 swap32((unsigned char *)&bytes
);
18981 fseek(fd
, 40, SEEK_SET
); // jump to data length
18982 fwrite(&bytes
, 4, 1, fd
);
18984 bytes
= totalCount
* channels
* bytes_per_sample
+ 44;
18985 if( !little_endian
)
18986 swap32((unsigned char *)&bytes
);
18988 fseek(fd
, 4, SEEK_SET
); // jump to file size
18989 fwrite(&bytes
, 4, 1, fd
);
18993 bool WvOut :: setSndFile( const char *fileName
)
18996 strncpy(name
, fileName
, 128);
18997 if ( strstr(name
, ".snd") == NULL
) strcat(name
, ".snd");
18998 fd
= fopen(name
, "wb");
19000 sprintf(msg
, "[chuck](via WvOut): Could not create SND file: %s", name
);
19004 struct sndhdr hdr
= {".sn", 40, 0, 3, (SINT32
) Stk::sampleRate(), 1, "Created by STK"};
19006 hdr
.num_channels
= channels
;
19007 if ( dataType
== STK_SINT8
)
19009 else if ( dataType
== STK_SINT16
)
19011 else if ( dataType
== STK_SINT32
)
19013 else if ( dataType
== MY_FLOAT32
)
19015 else if ( dataType
== MY_FLOAT64
)
19019 if( little_endian
)
19022 swap32 ((unsigned char *)&hdr
.hdr_length
);
19023 swap32 ((unsigned char *)&hdr
.format
);
19024 swap32 ((unsigned char *)&hdr
.sample_rate
);
19025 swap32 ((unsigned char *)&hdr
.num_channels
);
19028 if ( fwrite(&hdr
, 4, 10, fd
) != 10 ) {
19029 sprintf(msg
, "[chuck](via WvOut): Could not write SND header for file %s", name
);
19033 // printf("\nCreating SND file: %s\n", name);
19037 void WvOut :: closeSndFile( void )
19039 int bytes_per_sample
= 1;
19040 if ( dataType
== STK_SINT16
)
19041 bytes_per_sample
= 2;
19042 else if ( dataType
== STK_SINT32
)
19043 bytes_per_sample
= 4;
19044 else if ( dataType
== MY_FLOAT32
)
19045 bytes_per_sample
= 4;
19046 else if ( dataType
== MY_FLOAT64
)
19047 bytes_per_sample
= 8;
19049 SINT32 bytes
= totalCount
* bytes_per_sample
* channels
;
19050 if( little_endian
)
19051 swap32 ((unsigned char *)&bytes
);
19053 fseek(fd
, 8, SEEK_SET
); // jump to data size
19054 fwrite(&bytes
, 4, 1, fd
);
19058 bool WvOut :: setAifFile( const char *fileName
)
19061 strncpy(name
, fileName
, 128);
19062 if ( strstr(name
, ".aif") == NULL
) strcat(name
, ".aif");
19063 fd
= fopen(name
, "wb");
19065 sprintf(msg
, "[chuck](via WvOut): Could not create AIF file: %s", name
);
19069 // Common parts of AIFF/AIFC header.
19070 struct aifhdr hdr
= {"FOR", 46, "AIF", "COM", 18, 0, 0, 16, "0"};
19071 struct aifssnd ssnd
= {"SSN", 8, 0, 0};
19075 ssnd
.ssnd
[3] = 'D';
19076 hdr
.num_chans
= channels
;
19077 if ( dataType
== STK_SINT8
)
19078 hdr
.sample_size
= 8;
19079 else if ( dataType
== STK_SINT16
)
19080 hdr
.sample_size
= 16;
19081 else if ( dataType
== STK_SINT32
)
19082 hdr
.sample_size
= 32;
19083 else if ( dataType
== MY_FLOAT32
) {
19085 hdr
.sample_size
= 32;
19086 hdr
.comm_size
= 24;
19088 else if ( dataType
== MY_FLOAT64
) {
19090 hdr
.sample_size
= 64;
19091 hdr
.comm_size
= 24;
19094 // For AIFF files, the sample rate is stored in a 10-byte,
19095 // IEEE Standard 754 floating point number, so we need to
19096 // convert to that.
19099 unsigned long rate
= (unsigned long) Stk::sampleRate();
19100 memset(hdr
.srate
, 0, 10);
19102 for (i
=0; i
<32; i
++) {
19107 if( little_endian
)
19108 swap16((unsigned char *)&i
);
19110 *(SINT16
*)(hdr
.srate
) = (SINT16
) i
;
19112 for (i
=32; i
; i
--) {
19113 if (rate
& 0x80000000) break;
19117 if( little_endian
)
19118 swap32((unsigned char *)&rate
);
19120 *(unsigned long *)(hdr
.srate
+2) = (unsigned long) rate
;
19123 if( little_endian
)
19126 swap32((unsigned char *)&hdr
.form_size
);
19127 swap32((unsigned char *)&hdr
.comm_size
);
19128 swap16((unsigned char *)&hdr
.num_chans
);
19129 swap16((unsigned char *)&hdr
.sample_size
);
19130 swap32((unsigned char *)&ssnd
.ssnd_size
);
19131 swap32((unsigned char *)&ssnd
.offset
);
19132 swap32((unsigned char *)&ssnd
.block_size
);
19135 // The structure boundaries don't allow a single write of 54 bytes.
19136 if ( fwrite(&hdr
, 4, 5, fd
) != 5 ) goto error
;
19137 if ( fwrite(&hdr
.num_chans
, 2, 1, fd
) != 1 ) goto error
;
19138 if ( fwrite(&hdr
.sample_frames
, 4, 1, fd
) != 1 ) goto error
;
19139 if ( fwrite(&hdr
.sample_size
, 2, 1, fd
) != 1 ) goto error
;
19140 if ( fwrite(&hdr
.srate
, 10, 1, fd
) != 1 ) goto error
;
19142 if ( dataType
== MY_FLOAT32
) {
19143 char type
[4] = {'f','l','3','2'};
19144 char zeroes
[2] = { 0, 0 };
19145 if ( fwrite(&type
, 4, 1, fd
) != 1 ) goto error
;
19146 if ( fwrite(&zeroes
, 2, 1, fd
) != 1 ) goto error
;
19148 else if ( dataType
== MY_FLOAT64
) {
19149 char type
[4] = {'f','l','6','4'};
19150 char zeroes
[2] = { 0, 0 };
19151 if ( fwrite(&type
, 4, 1, fd
) != 1 ) goto error
;
19152 if ( fwrite(&zeroes
, 2, 1, fd
) != 1 ) goto error
;
19155 if ( fwrite(&ssnd
, 4, 4, fd
) != 4 ) goto error
;
19157 // printf("\nCreating AIF file: %s\n", name);
19161 sprintf(msg
, "[chuck](via WvOut): Could not write AIF header for file %s", name
);
19165 void WvOut :: closeAifFile( void )
19167 unsigned long frames
= (unsigned long) totalCount
;
19168 if( little_endian
)
19169 swap32((unsigned char *)&frames
);
19171 fseek(fd
, 22, SEEK_SET
); // jump to "COMM" sample_frames
19172 fwrite(&frames
, 4, 1, fd
);
19174 int bytes_per_sample
= 1;
19175 if ( dataType
== STK_SINT16
)
19176 bytes_per_sample
= 2;
19177 else if ( dataType
== STK_SINT32
|| dataType
== MY_FLOAT32
)
19178 bytes_per_sample
= 4;
19179 else if ( dataType
== MY_FLOAT64
)
19180 bytes_per_sample
= 8;
19182 unsigned long bytes
= totalCount
* bytes_per_sample
* channels
+ 46;
19183 if ( dataType
== MY_FLOAT32
|| dataType
== MY_FLOAT64
) bytes
+= 6;
19184 if( little_endian
)
19185 swap32((unsigned char *)&bytes
);
19187 fseek(fd
, 4, SEEK_SET
); // jump to file size
19188 fwrite(&bytes
, 4, 1, fd
);
19190 bytes
= totalCount
* bytes_per_sample
* channels
+ 8;
19191 if ( dataType
== MY_FLOAT32
|| dataType
== MY_FLOAT64
) bytes
+= 6;
19192 if( little_endian
)
19193 swap32((unsigned char *)&bytes
);
19195 if ( dataType
== MY_FLOAT32
|| dataType
== MY_FLOAT64
)
19196 fseek(fd
, 48, SEEK_SET
); // jump to "SSND" chunk size
19198 fseek(fd
, 42, SEEK_SET
); // jump to "SSND" chunk size
19199 fwrite(&bytes
, 4, 1, fd
);
19204 bool WvOut :: setMatFile( const char *fileName
)
19207 strncpy(name
, fileName
, 128);
19208 if ( strstr(name
, ".mat") == NULL
) strcat(name
, ".mat");
19209 fd
= fopen(name
, "w+b");
19211 sprintf(msg
, "[chuck](via WvOut): Could not create MAT file: %s", name
);
19215 if ( dataType
!= MY_FLOAT64
) {
19216 dataType
= MY_FLOAT64
;
19217 sprintf(msg
, "[chuck](via WvOut): Using 64-bit floating-point data format for file %s", name
);
19218 handleError(msg
, StkError::WARNING
);
19222 strcpy(hdr
.heading
,"MATLAB 5.0 MAT-file, Generated using the Synthesis ToolKit in C++ (STK). By Perry R. Cook and Gary P. Scavone, 1995-2002.");
19225 for (i
=strlen(hdr
.heading
);i
<124;i
++) hdr
.heading
[i
] = ' ';
19227 // Header Flag Fields
19228 hdr
.hff
[0] = (SINT16
) 0x0100; // Version field
19229 hdr
.hff
[1] = (SINT16
) 'M'; // Endian indicator field ("MI")
19233 hdr
.adf
[0] = (SINT32
) 14; // Matlab array data type value
19234 hdr
.adf
[1] = (SINT32
) 0; // Size of file after this point to end (in bytes)
19235 // Don't know size yet.
19237 // Numeric Array Subelements (4):
19239 hdr
.adf
[2] = (SINT32
) 6; // Matlab 32-bit unsigned integer data type value
19240 hdr
.adf
[3] = (SINT32
) 8; // 8 bytes of data to follow
19241 hdr
.adf
[4] = (SINT32
) 6; // Double-precision array, no array flags set
19242 hdr
.adf
[5] = (SINT32
) 0; // 4 bytes undefined
19243 // 2. Array Dimensions
19244 hdr
.adf
[6] = (SINT32
) 5; // Matlab 32-bit signed integer data type value
19245 hdr
.adf
[7] = (SINT32
) 8; // 8 bytes of data to follow (2D array)
19246 hdr
.adf
[8] = (SINT32
) channels
; // This is the number of rows
19247 hdr
.adf
[9] = (SINT32
) 0; // This is the number of columns
19250 // We'll use fileName for the matlab array name (as well as the file name).
19251 // If fileName is 4 characters or less, we have to use a compressed data element
19252 // format for the array name data element. Otherwise, the array name must
19253 // be formatted in 8-byte increments (up to 31 characters + NULL).
19254 SINT32 namelength
= (SINT32
) strlen(fileName
);
19255 if (strstr(fileName
, ".mat")) namelength
-= 4;
19256 if (namelength
> 31) namelength
= 31; // Truncate name to 31 characters.
19257 char arrayName
[64];
19258 strncpy(arrayName
, fileName
, namelength
);
19259 arrayName
[namelength
] = '\0';
19260 if (namelength
> 4) {
19261 hdr
.adf
[10] = (SINT32
) 1; // Matlab 8-bit signed integer data type value
19263 else { // Compressed data element format
19264 hdr
.adf
[10] = namelength
;
19265 hdr
.adf
[10] <<= 16;
19268 SINT32 headsize
= 40; // Number of bytes in data element so far.
19270 // Write the fixed portion of the header
19271 if ( fwrite(&hdr
, 172, 1, fd
) != 1 ) goto error
;
19273 // Write MATLAB array name
19275 if (namelength
> 4) {
19276 if ( fwrite(&namelength
, 4, 1, fd
) != 1) goto error
;
19277 if ( fwrite(arrayName
, namelength
, 1, fd
) != 1 ) goto error
;
19278 tmp
= (SINT32
) ceil((float)namelength
/ 8);
19279 if ( fseek(fd
, tmp
*8-namelength
, SEEK_CUR
) == -1 ) goto error
;
19280 headsize
+= tmp
* 8;
19282 else { // Compressed data element format
19283 if ( fwrite(arrayName
, namelength
, 1, fd
) != 1 ) goto error
;
19284 tmp
= 4 - namelength
;
19285 if ( fseek(fd
, tmp
, SEEK_CUR
) == -1 ) goto error
;
19288 // Finish writing known header information
19289 tmp
= 9; // Matlab IEEE 754 double data type
19290 if ( fwrite(&tmp
, 4, 1, fd
) != 1 ) goto error
;
19291 tmp
= 0; // Size of real part subelement in bytes (8 per sample)
19292 if ( fwrite(&tmp
, 4, 1, fd
) != 1 ) goto error
;
19293 headsize
+= 8; // Total number of bytes in data element so far
19295 if ( fseek(fd
, 132, SEEK_SET
) == -1 ) goto error
;
19296 if ( fwrite(&headsize
, 4, 1, fd
) != 1 ) goto error
; // Write header size ... will update at end
19297 if ( fseek(fd
, 0, SEEK_END
) == -1 ) goto error
;
19300 fprintf( stderr
, "[chuck]:(via STK): creating MAT-file (%s) containing MATLAB array: %s\n", name
, arrayName
);
19304 sprintf(msg
, "[chuck](via WvOut): Could not write MAT-file header for file %s", name
);
19308 void WvOut :: closeMatFile( void )
19310 fseek(fd
, 164, SEEK_SET
); // jump to number of columns
19311 fwrite(&totalCount
, 4, 1, fd
);
19313 SINT32 headsize
, temp
;
19314 fseek(fd
, 132, SEEK_SET
); // jump to header size
19315 fread(&headsize
, 4, 1, fd
);
19317 headsize
+= (SINT32
) (totalCount
* 8 * channels
);
19318 fseek(fd
, 132, SEEK_SET
);
19319 // Write file size (minus some header info)
19320 fwrite(&headsize
, 4, 1, fd
);
19322 fseek(fd
, temp
+132, SEEK_SET
); // jumpt to data size (in bytes)
19323 temp
= totalCount
* 8 * channels
;
19324 fwrite(&temp
, 4, 1, fd
);
19329 unsigned long WvOut :: getFrames( void ) const
19334 MY_FLOAT
WvOut :: getTime( void ) const
19336 return (MY_FLOAT
) totalCount
/ Stk::sampleRate();
19339 void WvOut :: writeData( unsigned long frames
)
19341 if ( dataType
== STK_SINT8
) {
19342 if ( fileType
== WVOUT_WAV
) { // 8-bit WAV data is unsigned!
19343 unsigned char sample
;
19344 for ( unsigned long k
=0; k
<frames
*channels
; k
++ ) {
19345 sample
= (unsigned char) (data
[k
] * 127.0 + 128.0);
19346 if ( fwrite(&sample
, 1, 1, fd
) != 1 ) goto error
;
19350 signed char sample
;
19351 for ( unsigned long k
=0; k
<frames
*channels
; k
++ ) {
19352 sample
= (signed char) (data
[k
] * 127.0);
19353 //sample = ((signed char) (( data[k] + 1.0 ) * 127.5 + 0.5)) - 128;
19354 if ( fwrite(&sample
, 1, 1, fd
) != 1 ) goto error
;
19358 else if ( dataType
== STK_SINT16
) {
19360 for ( unsigned long k
=0; k
<frames
*channels
; k
++ ) {
19361 sample
= (SINT16
) (data
[k
] * 32767.0);
19362 //sample = ((SINT16) (( data[k] + 1.0 ) * 32767.5 + 0.5)) - 32768;
19363 if ( byteswap
) swap16( (unsigned char *)&sample
);
19364 if ( fwrite(&sample
, 2, 1, fd
) != 1 ) goto error
;
19367 else if ( dataType
== STK_SINT32
) {
19369 for ( unsigned long k
=0; k
<frames
*channels
; k
++ ) {
19370 sample
= (SINT32
) (data
[k
] * 2147483647.0);
19371 //sample = ((SINT32) (( data[k] + 1.0 ) * 2147483647.5 + 0.5)) - 2147483648;
19372 if ( byteswap
) swap32( (unsigned char *)&sample
);
19373 if ( fwrite(&sample
, 4, 1, fd
) != 1 ) goto error
;
19376 else if ( dataType
== MY_FLOAT32
) {
19378 for ( unsigned long k
=0; k
<frames
*channels
; k
++ ) {
19379 sample
= (FLOAT32
) (data
[k
]);
19380 if ( byteswap
) swap32( (unsigned char *)&sample
);
19381 if ( fwrite(&sample
, 4, 1, fd
) != 1 ) goto error
;
19384 else if ( dataType
== MY_FLOAT64
) {
19386 for ( unsigned long k
=0; k
<frames
*channels
; k
++ ) {
19387 sample
= (FLOAT64
) (data
[k
]);
19388 if ( byteswap
) swap64( (unsigned char *)&sample
);
19389 if ( fwrite(&sample
, 8, 1, fd
) != 1 ) goto error
;
19394 if( flush
>= 8192 )
19403 sprintf(msg
, "[chuck](via WvOut): Error writing data to file.");
19404 handleError(msg
, StkError::FILE_ERROR
);
19407 void WvOut :: tick(const MY_FLOAT sample
)
19411 for ( unsigned int j
=0; j
<channels
; j
++ )
19412 data
[counter
*channels
+j
] = sample
;
19417 if ( counter
== BUFFER_SIZE
) {
19418 writeData( BUFFER_SIZE
);
19423 void WvOut :: tick(const MY_FLOAT
*vector
, unsigned int vectorSize
)
19427 for (unsigned int i
=0; i
<vectorSize
; i
++)
19431 void WvOut :: tickFrame(const MY_FLOAT
*frameVector
, unsigned int frames
)
19436 for ( unsigned int i
=0; i
<frames
; i
++ ) {
19437 for ( j
=0; j
<channels
; j
++ ) {
19438 data
[counter
*channels
+j
] = frameVector
[i
*channels
+j
];
19443 if ( counter
== BUFFER_SIZE
) {
19444 writeData( BUFFER_SIZE
);
19453 // wrapper functions
19455 //convenience functions
19457 ck_domidi ( Instrmnt * inst, unsigned int i ) {
19458 unsigned char status = (i>>16)&&0xff;
19459 unsigned char data1 = (i>>8)&&0xff;
19460 unsigned char data2 = (i)&&0xff;
19465 ck_domidi ( Instrmnt * inst, unsigned char status, unsigned char data1, unsigned char data2) {
19466 unsigned char type = status && 0xf0;
19469 inst->noteOn( mtof ( (float)data1 ), ((float)data2) / 128.0 );
19471 case __SK_NoteOff_:
19472 inst->noteOff( ((float)data2) / 128.0 );
19474 case __SK_ControlChange_:
19475 inst->controlChange( data1, data2 );
19477 case __SK_AfterTouch_:
19478 inst->controlChange( __SK_AfterTouch_, ((float)data1) / 128.0 );
19479 case __SK_PitchBend_:
19480 unsigned int mnum = ((unsigned int)data2) << 7 || data1 );
19481 inst->controlChange( __SK_PitchBend_, ((float)mnum) / 16384.0 );
19488 UGEN_CTOR
BandedWG_ctor ( t_CKTIME now
) {
19489 return new BandedWG();
19492 UGEN_DTOR
BandedWG_dtor ( t_CKTIME now
, void * data
) {
19493 delete (BandedWG
*)data
;
19496 UGEN_TICK
BandedWG_tick ( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
) {
19497 *out
= ((BandedWG
*)data
)->tick();
19501 UGEN_PMSG
BandedWG_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
) {
19507 UGEN_CTRL
BandedWG_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
19509 BandedWG
* f
= (BandedWG
*)data
;
19510 f
->noteOn( GET_NEXT_FLOAT ( value
));
19513 UGEN_CTRL
BandedWG_ctrl_pluck( t_CKTIME now
, void * data
, void * value
)
19515 BandedWG
* f
= (BandedWG
*)data
;
19516 f
->pluck( GET_NEXT_FLOAT ( value
));
19519 UGEN_CTRL
BandedWG_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
19521 BandedWG
* f
= (BandedWG
*)data
;
19522 f
->noteOff( GET_NEXT_FLOAT ( value
));
19525 UGEN_CTRL
BandedWG_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
19527 BandedWG
* f
= (BandedWG
*)data
;
19528 f
->setFrequency( GET_NEXT_FLOAT ( value
));
19532 UGEN_CGET
BandedWG_cget_freq( t_CKTIME now
, void * data
, void * value
)
19534 BandedWG
* f
= (BandedWG
*)data
;
19535 SET_NEXT_FLOAT ( value
, f
->freakency
);
19538 UGEN_CTRL
BandedWG_ctrl_strikePosition( t_CKTIME now
, void * data
, void * value
)
19540 BandedWG
* f
= (BandedWG
*)data
;
19541 f
->setStrikePosition( GET_NEXT_FLOAT ( value
) );
19543 UGEN_CGET
BandedWG_cget_strikePosition( t_CKTIME now
, void * data
, void * value
)
19545 BandedWG
* f
= (BandedWG
*)data
;
19546 SET_NEXT_FLOAT ( value
, f
->strikePosition
);
19549 UGEN_CTRL
BandedWG_ctrl_bowRate( t_CKTIME now
, void * data
, void * value
)
19551 BandedWG
* f
= (BandedWG
*)data
;
19552 f
->m_rate
= GET_NEXT_FLOAT ( value
);
19554 UGEN_CGET
BandedWG_cget_bowRate( t_CKTIME now
, void * data
, void * value
)
19556 BandedWG
* f
= (BandedWG
*)data
;
19557 SET_NEXT_FLOAT ( value
, f
->m_rate
);
19560 UGEN_CTRL
BandedWG_ctrl_bowPressure( t_CKTIME now
, void * data
, void * value
)
19562 BandedWG
* f
= (BandedWG
*)data
;
19563 f
->controlChange( __SK_BowPressure_
, GET_NEXT_FLOAT(value
) * 128.0 );
19566 UGEN_CGET
BandedWG_cget_bowPressure( t_CKTIME now
, void * data
, void * value
)
19568 BandedWG
* f
= (BandedWG
*)data
;
19569 SET_NEXT_FLOAT ( value
, f
->m_bowpressure
);
19573 UGEN_CTRL
BandedWG_ctrl_preset( t_CKTIME now
, void * data
, void * value
)
19575 BandedWG
* f
= (BandedWG
*)data
;
19576 f
->setPreset ( GET_NEXT_INT ( value
) );
19579 UGEN_CGET
BandedWG_cget_preset( t_CKTIME now
, void * data
, void * value
)
19581 BandedWG
* f
= (BandedWG
*)data
;
19582 SET_NEXT_INT ( value
, f
->m_preset
);
19585 UGEN_CTRL
BandedWG_ctrl_startBowing( t_CKTIME now
, void * data
, void * value
)
19587 BandedWG
* f
= (BandedWG
*)data
;
19588 f
->startBowing( GET_NEXT_FLOAT (value
), f
->m_rate
);
19590 UGEN_CTRL
BandedWG_ctrl_stopBowing( t_CKTIME now
, void * data
, void * value
)
19592 BandedWG
* f
= (BandedWG
*)data
;
19593 f
->stopBowing( GET_NEXT_FLOAT (value
) );
19609 UGEN_CTOR
BiQuad_ctor( t_CKTIME now
)
19611 BiQuad_
* d
= new BiQuad_
;
19621 UGEN_DTOR
BiQuad_dtor( t_CKTIME now
, void * data
)
19623 delete (BiQuad_
*)data
;
19626 UGEN_TICK
BiQuad_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
19628 BiQuad_
* f
= (BiQuad_
*)data
;
19629 *out
= (SAMPLE
)f
->biquad
.tick( in
);
19633 UGEN_PMSG
BiQuad_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
19638 UGEN_CTRL
BiQuad_ctrl_b2( t_CKTIME now
, void * data
, void * value
)
19640 BiQuad_
* f
= (BiQuad_
*)data
;
19641 f
->biquad
.setB2( GET_NEXT_FLOAT(value
) );
19644 UGEN_CTRL
BiQuad_ctrl_b1( t_CKTIME now
, void * data
, void * value
)
19646 BiQuad_
* f
= (BiQuad_
*)data
;
19647 f
->biquad
.setB1( GET_NEXT_FLOAT(value
) );
19650 UGEN_CTRL
BiQuad_ctrl_b0( t_CKTIME now
, void * data
, void * value
)
19652 BiQuad_
* f
= (BiQuad_
*)data
;
19653 f
->biquad
.setB0( GET_NEXT_FLOAT(value
) );
19656 UGEN_CTRL
BiQuad_ctrl_a2( t_CKTIME now
, void * data
, void * value
)
19658 BiQuad_
* f
= (BiQuad_
*)data
;
19659 f
->biquad
.setA2( GET_NEXT_FLOAT(value
) );
19662 UGEN_CTRL
BiQuad_ctrl_a1( t_CKTIME now
, void * data
, void * value
)
19664 BiQuad_
* f
= (BiQuad_
*)data
;
19665 f
->biquad
.setA1( GET_NEXT_FLOAT(value
) );
19668 UGEN_CTRL
BiQuad_ctrl_pfreq( t_CKTIME now
, void * data
, void * value
)
19670 BiQuad_
* f
= (BiQuad_
*)data
;
19671 f
->pfreq
= GET_NEXT_FLOAT(value
);
19672 f
->biquad
.setResonance( f
->pfreq
, f
->prad
, f
->norm
!= 0 );
19675 UGEN_CTRL
BiQuad_ctrl_prad( t_CKTIME now
, void * data
, void * value
)
19677 BiQuad_
* f
= (BiQuad_
*)data
;
19678 f
->prad
= GET_NEXT_FLOAT(value
);
19679 f
->biquad
.setResonance( f
->pfreq
, f
->prad
, f
->norm
!= 0 );
19682 UGEN_CTRL
BiQuad_ctrl_zfreq( t_CKTIME now
, void * data
, void * value
)
19684 BiQuad_
* f
= (BiQuad_
*)data
;
19685 f
->zfreq
= GET_NEXT_FLOAT(value
);
19686 f
->biquad
.setNotch( f
->zfreq
, f
->zrad
);
19689 UGEN_CTRL
BiQuad_ctrl_zrad( t_CKTIME now
, void * data
, void * value
)
19691 BiQuad_
* f
= (BiQuad_
*)data
;
19692 f
->zrad
= GET_NEXT_FLOAT(value
);
19693 f
->biquad
.setNotch( f
->zfreq
, f
->zrad
);
19696 UGEN_CTRL
BiQuad_ctrl_norm( t_CKTIME now
, void * data
, void * value
)
19698 BiQuad_
* f
= (BiQuad_
*)data
;
19699 f
->norm
= GET_NEXT_UINT(value
) != 0;
19700 f
->biquad
.setResonance( f
->pfreq
, f
->prad
, f
->norm
!= 0 );
19703 UGEN_CTRL
BiQuad_ctrl_eqzs( t_CKTIME now
, void * data
, void * value
)
19705 BiQuad_
* f
= (BiQuad_
*)data
;
19706 f
->biquad
.setEqualGainZeroes();
19709 UGEN_CGET
BiQuad_cget_b2( t_CKTIME now
, void * data
, void * value
)
19711 BiQuad_
* f
= (BiQuad_
*)data
;
19712 SET_NEXT_FLOAT( value
, f
->biquad
.b
[2] );
19715 UGEN_CGET
BiQuad_cget_b1( t_CKTIME now
, void * data
, void * value
)
19717 BiQuad_
* f
= (BiQuad_
*)data
;
19718 SET_NEXT_FLOAT( value
, f
->biquad
.b
[1] );
19721 UGEN_CGET
BiQuad_cget_b0( t_CKTIME now
, void * data
, void * value
)
19723 BiQuad_
* f
= (BiQuad_
*)data
;
19724 SET_NEXT_FLOAT( value
, f
->biquad
.b
[0] );
19727 UGEN_CGET
BiQuad_cget_a2( t_CKTIME now
, void * data
, void * value
)
19729 BiQuad_
* f
= (BiQuad_
*)data
;
19730 SET_NEXT_FLOAT( value
, f
->biquad
.a
[2] );
19733 UGEN_CGET
BiQuad_cget_a1( t_CKTIME now
, void * data
, void * value
)
19735 BiQuad_
* f
= (BiQuad_
*)data
;
19736 SET_NEXT_FLOAT( value
, f
->biquad
.a
[1] );
19739 UGEN_CGET
BiQuad_cget_a0( t_CKTIME now
, void * data
, void * value
)
19741 BiQuad_
* f
= (BiQuad_
*)data
;
19742 SET_NEXT_FLOAT( value
, f
->biquad
.a
[0] );
19746 UGEN_CTOR
BlowBotl_ctor( t_CKTIME now
)
19748 return new BlowBotl();
19751 UGEN_DTOR
BlowBotl_dtor( t_CKTIME now
, void * data
)
19753 delete (BlowBotl
*)data
;
19756 UGEN_TICK
BlowBotl_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
19758 BlowBotl
* p
= (BlowBotl
*)data
;
19763 UGEN_PMSG
BlowBotl_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
19768 UGEN_CTRL
BlowBotl_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
19770 BlowBotl
* p
= (BlowBotl
*)data
;
19771 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19776 UGEN_CTRL
BlowBotl_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
19778 BlowBotl
* p
= (BlowBotl
*)data
;
19779 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19783 UGEN_CTRL
BlowBotl_ctrl_startBlowing( t_CKTIME now
, void * data
, void * value
)
19785 BlowBotl
* p
= (BlowBotl
*)data
;
19786 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19787 p
->startBlowing ( f
);
19790 UGEN_CTRL
BlowBotl_ctrl_stopBlowing( t_CKTIME now
, void * data
, void * value
)
19792 BlowBotl
* p
= (BlowBotl
*)data
;
19793 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19794 p
->stopBlowing ( f
);
19797 UGEN_CTRL
BlowBotl_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
19799 BlowBotl
* p
= (BlowBotl
*)data
;
19800 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19801 p
->setFrequency( f
);
19804 UGEN_CGET
BlowBotl_cget_freq ( t_CKTIME now
, void * data
, void * value
)
19806 BlowBotl
* p
= (BlowBotl
*)data
;
19807 SET_NEXT_FLOAT( value
, p
->baseFrequency
);
19811 UGEN_CTRL
BlowBotl_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
19813 BlowBotl
* p
= (BlowBotl
*)data
;
19814 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19818 UGEN_CGET
BlowBotl_cget_rate ( t_CKTIME now
, void * data
, void * value
)
19820 BlowBotl
* p
= (BlowBotl
*)data
;
19821 SET_NEXT_FLOAT( value
, p
->m_rate
);
19825 UGEN_CTOR
BlowHole_ctor( t_CKTIME now
)
19827 return new BlowHole( 44100 );
19830 UGEN_DTOR
BlowHole_dtor( t_CKTIME now
, void * data
)
19832 delete (BlowHole
*)data
;
19835 UGEN_TICK
BlowHole_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
19837 BlowHole
* p
= (BlowHole
*)data
;
19842 UGEN_PMSG
BlowHole_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
19847 UGEN_CTRL
BlowHole_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
19849 BlowHole
* p
= (BlowHole
*)data
;
19850 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19855 UGEN_CTRL
BlowHole_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
19857 BlowHole
* p
= (BlowHole
*)data
;
19858 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19862 UGEN_CTRL
BlowHole_ctrl_startBlowing( t_CKTIME now
, void * data
, void * value
)
19864 BlowHole
* p
= (BlowHole
*)data
;
19865 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19866 p
->startBlowing ( f
);
19869 UGEN_CTRL
BlowHole_ctrl_stopBlowing( t_CKTIME now
, void * data
, void * value
)
19871 BlowHole
* p
= (BlowHole
*)data
;
19872 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19873 p
->stopBlowing ( f
);
19876 UGEN_CTRL
BlowHole_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
19878 BlowHole
* p
= (BlowHole
*)data
;
19879 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19880 p
->setFrequency( f
);
19883 UGEN_CGET
BlowHole_cget_freq ( t_CKTIME now
, void * data
, void * value
)
19885 BlowHole
* p
= (BlowHole
*)data
;
19886 SET_NEXT_FLOAT( value
, p
->m_frequency
);
19890 UGEN_CTRL
BlowHole_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
19892 BlowHole
* p
= (BlowHole
*)data
;
19893 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19897 UGEN_CGET
BlowHole_cget_rate ( t_CKTIME now
, void * data
, void * value
)
19899 BlowHole
* p
= (BlowHole
*)data
;
19900 SET_NEXT_FLOAT( value
, p
->m_rate
);
19903 UGEN_CTRL
BlowHole_ctrl_tonehole( t_CKTIME now
, void * data
, void * value
)
19905 BlowHole
* p
= (BlowHole
*)data
;
19906 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19907 p
->setTonehole( f
);
19910 UGEN_CGET
BlowHole_cget_tonehole ( t_CKTIME now
, void * data
, void * value
)
19912 BlowHole
* p
= (BlowHole
*)data
;
19913 SET_NEXT_FLOAT( value
, p
->m_tonehole
);
19916 UGEN_CTRL
BlowHole_ctrl_vent( t_CKTIME now
, void * data
, void * value
)
19918 BlowHole
* p
= (BlowHole
*)data
;
19919 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19923 UGEN_CGET
BlowHole_cget_vent ( t_CKTIME now
, void * data
, void * value
)
19925 BlowHole
* p
= (BlowHole
*)data
;
19926 SET_NEXT_FLOAT( value
, p
->m_vent
);
19929 UGEN_CTRL
BlowHole_ctrl_reed( t_CKTIME now
, void * data
, void * value
)
19931 BlowHole
* p
= (BlowHole
*)data
;
19932 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19933 p
->controlChange(__SK_ReedStiffness_
, f
* 128.0);
19936 UGEN_CGET
BlowHole_cget_reed ( t_CKTIME now
, void * data
, void * value
)
19938 BlowHole
* p
= (BlowHole
*)data
;
19939 SET_NEXT_FLOAT( value
, p
->m_reed
);
19944 UGEN_CTOR
Bowed_ctor( t_CKTIME now
)
19946 return new Bowed(40.0);
19949 UGEN_DTOR
Bowed_dtor( t_CKTIME now
, void * data
)
19951 delete (Bowed
*)data
;
19954 UGEN_TICK
Bowed_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
19956 Bowed
* p
= (Bowed
*)data
;
19961 UGEN_PMSG
Bowed_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
19966 UGEN_CTRL
Bowed_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
19968 Bowed
* p
= (Bowed
*)data
;
19969 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19973 UGEN_CTRL
Bowed_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
19975 Bowed
* p
= (Bowed
*)data
;
19976 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19980 UGEN_CTRL
Bowed_ctrl_startBowing( t_CKTIME now
, void * data
, void * value
)
19982 Bowed
* p
= (Bowed
*)data
;
19983 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19984 p
->startBowing ( f
);
19987 UGEN_CTRL
Bowed_ctrl_stopBowing( t_CKTIME now
, void * data
, void * value
)
19989 Bowed
* p
= (Bowed
*)data
;
19990 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19991 p
->stopBowing ( f
);
19994 UGEN_CTRL
Bowed_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
19996 Bowed
* p
= (Bowed
*)data
;
19997 t_CKFLOAT f
= GET_CK_FLOAT(value
);
19998 p
->setFrequency( f
);
20001 UGEN_CGET
Bowed_cget_freq ( t_CKTIME now
, void * data
, void * value
)
20003 Bowed
* p
= (Bowed
*)data
;
20004 SET_NEXT_FLOAT( value
, p
->m_frequency
);
20007 UGEN_CTRL
Bowed_ctrl_vibrato( t_CKTIME now
, void * data
, void * value
)
20009 Bowed
* p
= (Bowed
*)data
;
20010 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20011 p
->setVibrato( f
);
20014 UGEN_CGET
Bowed_cget_vibrato( t_CKTIME now
, void * data
, void * value
)
20016 Bowed
* p
= (Bowed
*)data
;
20017 SET_NEXT_FLOAT( value
, p
->vibratoGain
);
20020 UGEN_CTRL
Bowed_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
20022 Bowed
* p
= (Bowed
*)data
;
20023 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20027 UGEN_CGET
Bowed_cget_rate ( t_CKTIME now
, void * data
, void * value
)
20029 Bowed
* p
= (Bowed
*)data
;
20030 SET_NEXT_FLOAT( value
, p
->m_rate
);
20037 UGEN_CTOR
Chorus_ctor( t_CKTIME now
)
20039 return new Chorus( 44100 );
20042 UGEN_DTOR
Chorus_dtor( t_CKTIME now
, void * data
)
20044 delete (Chorus
*)data
;
20047 UGEN_TICK
Chorus_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20049 Chorus
* p
= (Chorus
*)data
;
20050 *out
= p
->tick(in
);
20054 UGEN_PMSG
Chorus_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20060 UGEN_CTRL
Chorus_ctrl_mix( t_CKTIME now
, void * data
, void * value
)
20062 Chorus
* p
= (Chorus
*)data
;
20063 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20064 p
->setEffectMix( f
);
20067 UGEN_CTRL
Chorus_ctrl_modDepth( t_CKTIME now
, void * data
, void * value
)
20069 Chorus
* p
= (Chorus
*)data
;
20070 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20072 p
->setModDepth( f
);
20075 UGEN_CTRL
Chorus_ctrl_modFreq( t_CKTIME now
, void * data
, void * value
)
20077 Chorus
* p
= (Chorus
*)data
;
20078 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20079 p
->setModFrequency( f
);
20082 UGEN_CGET
Chorus_cget_mix( t_CKTIME now
, void * data
, void * value
)
20084 Chorus
* p
= (Chorus
*)data
;
20085 SET_NEXT_FLOAT( value
, p
->effectMix
);
20088 UGEN_CGET
Chorus_cget_modDepth( t_CKTIME now
, void * data
, void * value
)
20090 Chorus
* p
= (Chorus
*)data
;
20091 SET_NEXT_FLOAT ( value
, p
->modDepth
);
20094 UGEN_CGET
Chorus_cget_modFreq( t_CKTIME now
, void * data
, void * value
)
20096 Chorus
* p
= (Chorus
*)data
;
20097 SET_NEXT_FLOAT ( value
, p
->mods
[0]->m_freq
);
20104 double m_frequency
;
20108 Brass_ ( double d
) {
20109 imp
= new Brass(d
);
20110 m_frequency
= 100.0;
20116 UGEN_CTOR
Brass_ctor( t_CKTIME now
)
20118 return new Brass_( 30.0 );
20121 UGEN_DTOR
Brass_dtor( t_CKTIME now
, void * data
)
20123 delete ((Brass_
*)data
)->imp
;
20124 delete (Brass_
*)data
;
20127 UGEN_TICK
Brass_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20129 Brass_
* b
= (Brass_
*)data
;
20130 *out
= b
->imp
->tick();
20134 UGEN_PMSG
Brass_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20139 UGEN_CTRL
Brass_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
20141 Brass_
* b
= (Brass_
*)data
;
20142 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20143 b
->imp
->noteOn ( b
->m_frequency
, f
);
20147 UGEN_CTRL
Brass_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
20149 Brass_
* b
= (Brass_
*)data
;
20150 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20151 b
->imp
->noteOff ( f
);
20154 UGEN_CTRL
Brass_ctrl_startBlowing( t_CKTIME now
, void * data
, void * value
)
20156 Brass_
* b
= (Brass_
*)data
;
20157 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20158 b
->imp
->startBlowing ( f
, b
->m_rate
);
20161 UGEN_CTRL
Brass_ctrl_stopBlowing( t_CKTIME now
, void * data
, void * value
)
20163 Brass_
* b
= (Brass_
*)data
;
20164 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20165 b
->imp
->stopBlowing ( f
);
20168 UGEN_CTRL
Brass_ctrl_clear( t_CKTIME now
, void * data
, void * value
)
20170 Brass_
* b
= (Brass_
*)data
;
20174 UGEN_CTRL
Brass_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
20176 Brass_
* b
= (Brass_
*)data
;
20177 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20178 b
->m_frequency
= f
;
20179 b
->imp
->setFrequency( f
);
20182 UGEN_CGET
Brass_cget_freq ( t_CKTIME now
, void * data
, void * value
)
20184 Brass_
* b
= (Brass_
*)data
;
20185 SET_NEXT_FLOAT( value
, b
->m_frequency
);
20188 UGEN_CTRL
Brass_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
20190 Brass_
* b
= (Brass_
*)data
;
20191 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20195 UGEN_CGET
Brass_cget_rate ( t_CKTIME now
, void * data
, void * value
)
20197 Brass_
* b
= (Brass_
*)data
;
20198 SET_NEXT_FLOAT( value
, b
->m_rate
);
20201 UGEN_CTRL
Brass_ctrl_lip( t_CKTIME now
, void * data
, void * value
)
20203 Brass_
* b
= (Brass_
*)data
;
20204 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20209 UGEN_CGET
Brass_cget_lip ( t_CKTIME now
, void * data
, void * value
)
20211 Brass_
* b
= (Brass_
*)data
;
20212 SET_NEXT_FLOAT( value
, b
->m_lip
);
20218 double m_frequency
;
20221 Clarinet_ ( double d
) {
20222 imp
= new Clarinet(d
);
20223 m_frequency
= 100.0;
20231 UGEN_CTOR
Clarinet_ctor( t_CKTIME now
)
20233 return new Clarinet_( 40.0 );
20236 UGEN_DTOR
Clarinet_dtor( t_CKTIME now
, void * data
)
20238 delete ((Clarinet_
*)data
)->imp
;
20239 delete (Clarinet_
*)data
;
20242 UGEN_TICK
Clarinet_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20244 Clarinet_
* b
= (Clarinet_
*)data
;
20245 *out
= b
->imp
->tick();
20249 UGEN_PMSG
Clarinet_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20254 UGEN_CTRL
Clarinet_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
20256 Clarinet_
* b
= (Clarinet_
*)data
;
20257 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20258 b
->imp
->noteOn ( b
->m_frequency
, f
);
20262 UGEN_CTRL
Clarinet_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
20264 Clarinet_
* b
= (Clarinet_
*)data
;
20265 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20266 b
->imp
->noteOff ( f
);
20269 UGEN_CTRL
Clarinet_ctrl_startBlowing( t_CKTIME now
, void * data
, void * value
)
20271 Clarinet_
* b
= (Clarinet_
*)data
;
20272 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20273 b
->imp
->startBlowing ( f
, b
->m_rate
);
20276 UGEN_CTRL
Clarinet_ctrl_stopBlowing( t_CKTIME now
, void * data
, void * value
)
20278 Clarinet_
* b
= (Clarinet_
*)data
;
20279 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20280 b
->imp
->stopBlowing ( f
);
20283 UGEN_CTRL
Clarinet_ctrl_clear( t_CKTIME now
, void * data
, void * value
)
20285 Clarinet_
* b
= (Clarinet_
*)data
;
20289 UGEN_CTRL
Clarinet_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
20291 Clarinet_
* b
= (Clarinet_
*)data
;
20292 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20293 b
->m_frequency
= f
;
20294 b
->imp
->setFrequency( f
);
20297 UGEN_CGET
Clarinet_cget_freq ( t_CKTIME now
, void * data
, void * value
)
20299 Clarinet_
* b
= (Clarinet_
*)data
;
20300 SET_NEXT_FLOAT( value
, b
->m_frequency
);
20303 UGEN_CTRL
Clarinet_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
20305 Clarinet_
* b
= (Clarinet_
*)data
;
20306 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20310 UGEN_CGET
Clarinet_cget_rate ( t_CKTIME now
, void * data
, void * value
)
20312 Clarinet_
* b
= (Clarinet_
*)data
;
20313 SET_NEXT_FLOAT( value
, b
->m_rate
);
20320 double m_frequency
;
20323 double m_jetReflection
;
20324 double m_endReflection
;
20326 Flute_ ( double d
) {
20327 imp
= new Flute(d
);
20328 m_frequency
= 100.0;
20331 m_jetReflection
= 0.0;
20332 m_endReflection
= 0.0;
20336 UGEN_CTOR
Flute_ctor( t_CKTIME now
)
20338 return new Flute_( 40.0 );
20341 UGEN_DTOR
Flute_dtor( t_CKTIME now
, void * data
)
20343 delete ((Flute_
*)data
)->imp
;
20344 delete (Flute_
*)data
;
20347 UGEN_TICK
Flute_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20349 Flute_
* b
= (Flute_
*)data
;
20350 *out
= b
->imp
->tick();
20354 UGEN_PMSG
Flute_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20359 UGEN_CTRL
Flute_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
20361 Flute_
* b
= (Flute_
*)data
;
20362 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20363 b
->imp
->noteOn ( b
->m_frequency
, f
);
20367 UGEN_CTRL
Flute_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
20369 Flute_
* b
= (Flute_
*)data
;
20370 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20371 b
->imp
->noteOff ( f
);
20374 UGEN_CTRL
Flute_ctrl_startBlowing( t_CKTIME now
, void * data
, void * value
)
20376 Flute_
* b
= (Flute_
*)data
;
20377 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20378 b
->imp
->startBlowing ( f
, b
->m_rate
);
20381 UGEN_CTRL
Flute_ctrl_stopBlowing( t_CKTIME now
, void * data
, void * value
)
20383 Flute_
* b
= (Flute_
*)data
;
20384 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20385 b
->imp
->stopBlowing ( f
);
20388 UGEN_CTRL
Flute_ctrl_clear( t_CKTIME now
, void * data
, void * value
)
20390 Flute_
* b
= (Flute_
*)data
;
20394 UGEN_CTRL
Flute_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
20396 Flute_
* b
= (Flute_
*)data
;
20397 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20398 b
->m_frequency
= f
;
20399 b
->imp
->setFrequency( f
);
20402 UGEN_CGET
Flute_cget_freq ( t_CKTIME now
, void * data
, void * value
)
20404 Flute_
* b
= (Flute_
*)data
;
20405 SET_NEXT_FLOAT( value
, b
->m_frequency
);
20408 UGEN_CTRL
Flute_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
20410 Flute_
* b
= (Flute_
*)data
;
20411 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20415 UGEN_CGET
Flute_cget_rate ( t_CKTIME now
, void * data
, void * value
)
20417 Flute_
* b
= (Flute_
*)data
;
20418 SET_NEXT_FLOAT( value
, b
->m_rate
);
20421 UGEN_CTRL
Flute_ctrl_jetDelay( t_CKTIME now
, void * data
, void * value
)
20423 Flute_
* b
= (Flute_
*)data
;
20424 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20426 b
->imp
->setJetDelay( f
);
20429 UGEN_CGET
Flute_cget_jetDelay ( t_CKTIME now
, void * data
, void * value
)
20431 Flute_
* b
= (Flute_
*)data
;
20432 SET_NEXT_FLOAT( value
, b
->m_jetDelay
);
20435 UGEN_CTRL
Flute_ctrl_jetReflection( t_CKTIME now
, void * data
, void * value
)
20437 Flute_
* b
= (Flute_
*)data
;
20438 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20439 b
->m_jetReflection
= f
;
20440 b
->imp
->setJetReflection( f
);
20443 UGEN_CGET
Flute_cget_jetReflection ( t_CKTIME now
, void * data
, void * value
)
20445 Flute_
* b
= (Flute_
*)data
;
20446 SET_NEXT_FLOAT( value
, b
->m_jetReflection
);
20449 UGEN_CTRL
Flute_ctrl_endReflection( t_CKTIME now
, void * data
, void * value
)
20451 Flute_
* b
= (Flute_
*)data
;
20452 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20453 b
->m_endReflection
= f
;
20454 b
->imp
->setEndReflection(f
);
20457 UGEN_CGET
Flute_cget_endReflection ( t_CKTIME now
, void * data
, void * value
)
20459 Flute_
* b
= (Flute_
*)data
;
20460 SET_NEXT_FLOAT( value
, b
->m_endReflection
);
20470 double m_modeRatio
;
20471 double m_modeRadius
;
20479 UGEN_CTOR
ModalBar_ctor( t_CKTIME now
)
20481 return new ModalBar_();
20484 UGEN_DTOR
ModalBar_dtor( t_CKTIME now
, void * data
)
20486 delete (ModalBar
*)data
;
20489 UGEN_TICK
ModalBar_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20491 ModalBar_
* b
= (ModalBar_
*)data
;
20492 *out
= b
->modalbar
.tick();
20496 UGEN_PMSG
ModalBar_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20501 UGEN_CTRL
ModalBar_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
20503 ModalBar_
* b
= (ModalBar_
*)data
;
20504 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20505 b
->modalbar
.noteOn ( b
->modalbar
.baseFrequency
, f
);
20508 UGEN_CTRL
ModalBar_ctrl_strike( t_CKTIME now
, void * data
, void * value
)
20510 ModalBar_
* b
= (ModalBar_
*)data
;
20511 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20512 b
->modalbar
.strike ( f
);
20515 UGEN_CTRL
ModalBar_ctrl_damp( t_CKTIME now
, void * data
, void * value
)
20517 ModalBar_
* b
= (ModalBar_
*)data
;
20518 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20519 b
->modalbar
.damp ( f
);
20522 UGEN_CTRL
ModalBar_ctrl_clear( t_CKTIME now
, void * data
, void * value
)
20524 ModalBar_
* b
= (ModalBar_
*)data
;
20525 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20526 b
->modalbar
.clear ();
20529 UGEN_CTRL
ModalBar_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
20531 ModalBar_
* b
= (ModalBar_
*)data
;
20532 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20533 b
->modalbar
.noteOn ( b
->modalbar
.baseFrequency
, f
);
20536 UGEN_CTRL
ModalBar_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
20538 ModalBar_
* b
= (ModalBar_
*)data
;
20539 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20540 b
->modalbar
.setFrequency ( f
);
20543 UGEN_CGET
ModalBar_cget_freq( t_CKTIME now
, void * data
, void * value
)
20545 ModalBar_
* b
= (ModalBar_
*)data
;
20546 SET_NEXT_FLOAT( value
, b
->modalbar
.baseFrequency
);
20550 UGEN_CTRL
ModalBar_ctrl_preset( t_CKTIME now
, void * data
, void * value
)
20552 ModalBar_
* b
= (ModalBar_
*)data
;
20553 int f
= GET_CK_INT(value
);
20555 b
->modalbar
.setPreset ( f
);
20558 UGEN_CGET
ModalBar_cget_preset( t_CKTIME now
, void * data
, void * value
)
20560 ModalBar_
* b
= (ModalBar_
*)data
;
20561 SET_NEXT_INT( value
, b
->m_preset
);
20564 UGEN_CTRL
ModalBar_ctrl_strikePosition( t_CKTIME now
, void * data
, void * value
)
20566 ModalBar_
* b
= (ModalBar_
*)data
;
20567 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20568 b
->modalbar
.setStrikePosition ( f
);
20571 UGEN_CGET
ModalBar_cget_strikePosition( t_CKTIME now
, void * data
, void * value
)
20573 ModalBar_
* b
= (ModalBar_
*)data
;
20574 SET_NEXT_FLOAT( value
, b
->modalbar
.strikePosition
);
20577 UGEN_CTRL
ModalBar_ctrl_stickHardness( t_CKTIME now
, void * data
, void * value
)
20579 ModalBar_
* b
= (ModalBar_
*)data
;
20580 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20581 b
->modalbar
.setStickHardness ( f
);
20584 UGEN_CGET
ModalBar_cget_stickHardness( t_CKTIME now
, void * data
, void * value
)
20586 ModalBar_
* b
= (ModalBar_
*)data
;
20587 SET_NEXT_FLOAT( value
, b
->modalbar
.stickHardness
);
20589 UGEN_CTRL
ModalBar_ctrl_masterGain( t_CKTIME now
, void * data
, void * value
)
20591 ModalBar_
* b
= (ModalBar_
*)data
;
20592 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20593 b
->modalbar
.setMasterGain ( f
);
20596 UGEN_CGET
ModalBar_cget_masterGain( t_CKTIME now
, void * data
, void * value
)
20598 ModalBar_
* b
= (ModalBar_
*)data
;
20599 SET_NEXT_FLOAT( value
, b
->modalbar
.masterGain
);
20602 UGEN_CTRL
ModalBar_ctrl_directGain( t_CKTIME now
, void * data
, void * value
)
20604 ModalBar_
* b
= (ModalBar_
*)data
;
20605 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20606 b
->modalbar
.setDirectGain ( f
);
20609 UGEN_CGET
ModalBar_cget_directGain( t_CKTIME now
, void * data
, void * value
)
20611 ModalBar_
* b
= (ModalBar_
*)data
;
20612 SET_NEXT_FLOAT( value
, b
->modalbar
.directGain
);
20616 UGEN_CTRL
ModalBar_ctrl_mode( t_CKTIME now
, void * data
, void * value
)
20618 ModalBar_
* b
= (ModalBar_
*)data
;
20619 int i
= GET_CK_INT(value
);
20620 if ( i
>= 0 && i
< b
->modalbar
.nModes
) {
20621 b
->m_modeIndex
= i
;
20622 b
->m_modeRatio
= b
->modalbar
.ratios
[i
];
20623 b
->m_modeRadius
= b
->modalbar
.radii
[i
];
20627 UGEN_CGET
ModalBar_cget_mode( t_CKTIME now
, void * data
, void * value
)
20629 ModalBar_
* b
= (ModalBar_
*)data
;
20630 SET_NEXT_FLOAT( value
, b
->m_modeIndex
);
20633 UGEN_CTRL
ModalBar_ctrl_modeGain( t_CKTIME now
, void * data
, void * value
)
20635 ModalBar_
* b
= (ModalBar_
*)data
;
20636 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20637 b
->modalbar
.setModeGain ( b
->m_modeIndex
, f
);
20640 UGEN_CGET
ModalBar_cget_modeGain( t_CKTIME now
, void * data
, void * value
)
20642 ModalBar_
* b
= (ModalBar_
*)data
;
20643 SET_NEXT_FLOAT( value
, b
->modalbar
.filters
[b
->m_modeIndex
]->getGain() );
20646 UGEN_CTRL
ModalBar_ctrl_modeRatio( t_CKTIME now
, void * data
, void * value
)
20648 ModalBar_
* b
= (ModalBar_
*)data
;
20649 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20650 if ( b
->m_modeIndex
>= 0 && b
->m_modeIndex
< b
->modalbar
.nModes
) {
20651 b
->modalbar
.setRatioAndRadius ( b
->m_modeIndex
, f
, b
->m_modeRadius
);
20652 b
->m_modeRatio
= b
->modalbar
.ratios
[b
->m_modeIndex
];
20656 UGEN_CGET
ModalBar_cget_modeRatio( t_CKTIME now
, void * data
, void * value
)
20658 ModalBar_
* b
= (ModalBar_
*)data
;
20659 SET_NEXT_FLOAT( value
, b
->m_modeRatio
);
20662 UGEN_CTRL
ModalBar_ctrl_modeRadius( t_CKTIME now
, void * data
, void * value
)
20664 ModalBar_
* b
= (ModalBar_
*)data
;
20665 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20666 if ( b
->m_modeIndex
>= 0 && b
->m_modeIndex
< b
->modalbar
.nModes
) {
20667 b
->modalbar
.setRatioAndRadius ( b
->m_modeIndex
, b
->m_modeRatio
, f
);
20668 b
->m_modeRadius
= b
->modalbar
.radii
[b
->m_modeIndex
];
20672 UGEN_CGET
ModalBar_cget_modeRadius( t_CKTIME now
, void * data
, void * value
)
20674 ModalBar_
* b
= (ModalBar_
*)data
;
20675 SET_NEXT_FLOAT( value
, b
->m_modeRadius
);
20682 double m_frequency
;
20684 Sitar_ ( double d
) {
20685 imp
= new Sitar(d
);
20686 m_frequency
= 100.0;
20690 UGEN_CTOR
Sitar_ctor( t_CKTIME now
)
20692 return new Sitar_( 30.0 );
20695 UGEN_DTOR
Sitar_dtor( t_CKTIME now
, void * data
)
20697 delete ((Sitar_
*)data
)->imp
;
20698 delete (Sitar_
*)data
;
20701 UGEN_TICK
Sitar_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20703 Sitar_
* b
= (Sitar_
*)data
;
20704 *out
= b
->imp
->tick();
20708 UGEN_PMSG
Sitar_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20713 UGEN_CTRL
Sitar_ctrl_pluck( t_CKTIME now
, void * data
, void * value
)
20715 Sitar_
* b
= (Sitar_
*)data
;
20716 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20717 b
->imp
->pluck ( f
);
20720 UGEN_CTRL
Sitar_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
20722 Sitar_
* b
= (Sitar_
*)data
;
20723 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20724 b
->imp
->noteOn ( b
->m_frequency
, f
);
20727 UGEN_CTRL
Sitar_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
20729 Sitar_
* b
= (Sitar_
*)data
;
20730 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20731 b
->imp
->noteOff ( f
);
20734 UGEN_CTRL
Sitar_ctrl_clear( t_CKTIME now
, void * data
, void * value
)
20736 Sitar_
* b
= (Sitar_
*)data
;
20740 UGEN_CTRL
Sitar_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
20742 Sitar_
* b
= (Sitar_
*)data
;
20743 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20744 b
->m_frequency
= f
;
20745 b
->imp
->setFrequency( f
);
20748 UGEN_CGET
Sitar_cget_freq ( t_CKTIME now
, void * data
, void * value
)
20750 Sitar_
* b
= (Sitar_
*)data
;
20751 SET_NEXT_FLOAT( value
, b
->m_frequency
);
20760 double m_frequency
;
20763 Saxofony_ ( double d
) {
20764 imp
= new Saxofony(d
);
20765 m_frequency
= 100.0;
20770 UGEN_CTOR
Saxofony_ctor( t_CKTIME now
)
20772 return new Saxofony_( 30.0 );
20775 UGEN_DTOR
Saxofony_dtor( t_CKTIME now
, void * data
)
20777 delete ((Saxofony_
*)data
)->imp
;
20778 delete (Saxofony_
*)data
;
20781 UGEN_TICK
Saxofony_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20783 Saxofony_
* b
= (Saxofony_
*)data
;
20784 *out
= b
->imp
->tick();
20788 UGEN_PMSG
Saxofony_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20793 UGEN_CTRL
Saxofony_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
20795 Saxofony_
* b
= (Saxofony_
*)data
;
20796 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20797 b
->imp
->noteOn ( b
->m_frequency
, f
);
20801 UGEN_CTRL
Saxofony_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
20803 Saxofony_
* b
= (Saxofony_
*)data
;
20804 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20805 b
->imp
->noteOff ( f
);
20808 UGEN_CTRL
Saxofony_ctrl_startBlowing( t_CKTIME now
, void * data
, void * value
)
20810 Saxofony_
* b
= (Saxofony_
*)data
;
20811 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20812 b
->imp
->startBlowing ( f
, b
->m_rate
);
20815 UGEN_CTRL
Saxofony_ctrl_stopBlowing( t_CKTIME now
, void * data
, void * value
)
20817 Saxofony_
* b
= (Saxofony_
*)data
;
20818 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20819 b
->imp
->stopBlowing ( f
);
20822 UGEN_CTRL
Saxofony_ctrl_clear( t_CKTIME now
, void * data
, void * value
)
20824 Saxofony_
* b
= (Saxofony_
*)data
;
20828 UGEN_CTRL
Saxofony_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
20830 Saxofony_
* b
= (Saxofony_
*)data
;
20831 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20832 b
->m_frequency
= f
;
20833 b
->imp
->setFrequency( f
);
20836 UGEN_CGET
Saxofony_cget_freq ( t_CKTIME now
, void * data
, void * value
)
20838 Saxofony_
* b
= (Saxofony_
*)data
;
20839 SET_NEXT_FLOAT( value
, b
->m_frequency
);
20842 UGEN_CTRL
Saxofony_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
20844 Saxofony_
* b
= (Saxofony_
*)data
;
20845 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20849 UGEN_CGET
Saxofony_cget_rate ( t_CKTIME now
, void * data
, void * value
)
20851 Saxofony_
* b
= (Saxofony_
*)data
;
20852 SET_NEXT_FLOAT( value
, b
->m_rate
);
20855 UGEN_CTRL
Saxofony_ctrl_blowPosition( t_CKTIME now
, void * data
, void * value
)
20857 Saxofony_
* b
= (Saxofony_
*)data
;
20858 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20859 b
->imp
->setBlowPosition(f
);
20862 UGEN_CGET
Saxofony_cget_blowPosition ( t_CKTIME now
, void * data
, void * value
)
20864 Saxofony_
* b
= (Saxofony_
*)data
;
20865 SET_NEXT_FLOAT( value
, b
->imp
->position
);
20872 UGEN_CTOR
StifKarp_ctor( t_CKTIME now
)
20874 return new StifKarp( 30.0 );
20877 UGEN_DTOR
StifKarp_dtor( t_CKTIME now
, void * data
)
20879 delete (StifKarp
*)data
;
20882 UGEN_TICK
StifKarp_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20884 StifKarp
* b
= (StifKarp
*)data
;
20889 UGEN_PMSG
StifKarp_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20894 UGEN_CTRL
StifKarp_ctrl_pluck( t_CKTIME now
, void * data
, void * value
)
20896 StifKarp
* b
= (StifKarp
*)data
;
20897 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20901 UGEN_CTRL
StifKarp_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
20903 StifKarp
* b
= (StifKarp
*)data
;
20904 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20905 b
->noteOn ( b
->lastFrequency
, f
);
20908 UGEN_CTRL
StifKarp_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
20910 StifKarp
* b
= (StifKarp
*)data
;
20911 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20915 UGEN_CTRL
StifKarp_ctrl_clear( t_CKTIME now
, void * data
, void * value
)
20917 StifKarp
* b
= (StifKarp
*)data
;
20921 UGEN_CTRL
StifKarp_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
20923 StifKarp
* b
= (StifKarp
*)data
;
20924 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20925 b
->setFrequency( f
);
20928 UGEN_CGET
StifKarp_cget_freq ( t_CKTIME now
, void * data
, void * value
)
20930 StifKarp
* b
= (StifKarp
*)data
;
20931 SET_NEXT_FLOAT( value
, b
->lastFrequency
);
20934 UGEN_CTRL
StifKarp_ctrl_pickupPosition( t_CKTIME now
, void * data
, void * value
)
20936 StifKarp
* b
= (StifKarp
*)data
;
20937 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20938 b
->setPickupPosition( f
);
20941 UGEN_CGET
StifKarp_cget_pickupPosition( t_CKTIME now
, void * data
, void * value
)
20943 StifKarp
* b
= (StifKarp
*)data
;
20944 SET_NEXT_FLOAT( value
, b
->pickupPosition
);
20947 UGEN_CTRL
StifKarp_ctrl_stretch( t_CKTIME now
, void * data
, void * value
)
20949 StifKarp
* b
= (StifKarp
*)data
;
20950 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20951 b
->setStretch( f
);
20954 UGEN_CGET
StifKarp_cget_stretch( t_CKTIME now
, void * data
, void * value
)
20956 StifKarp
* b
= (StifKarp
*)data
;
20957 SET_NEXT_FLOAT( value
, b
->stretching
);
20960 UGEN_CTRL
StifKarp_ctrl_baseLoopGain( t_CKTIME now
, void * data
, void * value
)
20962 StifKarp
* b
= (StifKarp
*)data
;
20963 t_CKFLOAT f
= GET_CK_FLOAT(value
);
20964 b
->setBaseLoopGain( f
);
20967 UGEN_CGET
StifKarp_cget_baseLoopGain ( t_CKTIME now
, void * data
, void * value
)
20969 StifKarp
* b
= (StifKarp
*)data
;
20970 SET_NEXT_FLOAT( value
, b
->baseLoopGain
);
20975 UGEN_CTOR
Delay_ctor( t_CKTIME now
)
20980 UGEN_DTOR
Delay_dtor( t_CKTIME now
, void * data
)
20982 delete (Delay
*)data
;
20985 UGEN_TICK
Delay_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
20987 *out
= (SAMPLE
)((Delay
*)data
)->tick( in
);
20991 UGEN_PMSG
Delay_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
20996 UGEN_CTRL
Delay_ctrl_delay( t_CKTIME now
, void * data
, void * value
)
20998 ((Delay
*)data
)->setDelay( (long)(GET_NEXT_DUR(value
)+.5) );
21001 UGEN_CTRL
Delay_ctrl_max( t_CKTIME now
, void * data
, void * value
)
21003 Delay
* delay
= (Delay
*)data
;
21004 t_CKFLOAT val
= (t_CKFLOAT
)delay
->getDelay();
21005 t_CKDUR max
= GET_NEXT_DUR(value
);
21006 delay
->set( (long)(val
+.5), (long)(max
+1.5) );
21009 UGEN_CGET
Delay_cget_delay( t_CKTIME now
, void * data
, void * value
)
21011 SET_NEXT_DUR( value
, (t_CKDUR
)((Delay
*)data
)->getDelay() );
21014 UGEN_CGET
Delay_cget_max( t_CKTIME now
, void * data
, void * value
)
21016 SET_NEXT_DUR( value
, (t_CKDUR
)((Delay
*)data
)->length
-1.0 );
21021 UGEN_CTOR
DelayA_ctor( t_CKTIME now
)
21026 UGEN_DTOR
DelayA_dtor( t_CKTIME now
, void * data
)
21028 delete (DelayA
*)data
;
21031 UGEN_TICK
DelayA_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21033 *out
= (SAMPLE
)((DelayA
*)data
)->tick( in
);
21037 UGEN_PMSG
DelayA_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21042 UGEN_CTRL
DelayA_ctrl_delay( t_CKTIME now
, void * data
, void * value
)
21044 ((DelayA
*)data
)->setDelay( GET_NEXT_DUR(value
) );
21047 UGEN_CTRL
DelayA_ctrl_max( t_CKTIME now
, void * data
, void * value
)
21049 DelayA
* delay
= (DelayA
*)data
;
21050 t_CKDUR val
= (t_CKDUR
)delay
->getDelay();
21051 t_CKDUR max
= GET_NEXT_DUR(value
);
21052 delay
->set( val
, (long)(max
+1.5) );
21055 UGEN_CGET
DelayA_cget_delay( t_CKTIME now
, void * data
, void * value
)
21057 SET_NEXT_DUR( value
, (t_CKDUR
)((DelayA
*)data
)->getDelay() );
21060 UGEN_CGET
DelayA_cget_max( t_CKTIME now
, void * data
, void * value
)
21062 SET_NEXT_DUR( value
, (t_CKDUR
)((DelayA
*)data
)->length
-1.0 );
21067 UGEN_CTOR
DelayL_ctor( t_CKTIME now
)
21072 UGEN_DTOR
DelayL_dtor( t_CKTIME now
, void * data
)
21074 delete (DelayL
*)data
;
21077 UGEN_TICK
DelayL_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21079 *out
= (SAMPLE
)((DelayL
*)data
)->tick( in
);
21083 UGEN_PMSG
DelayL_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21088 UGEN_CTRL
DelayL_ctrl_delay( t_CKTIME now
, void * data
, void * value
)
21090 ((DelayL
*)data
)->setDelay( GET_NEXT_DUR(value
) );
21093 UGEN_CTRL
DelayL_ctrl_max( t_CKTIME now
, void * data
, void * value
)
21095 DelayL
* delay
= (DelayL
*)data
;
21096 t_CKDUR val
= (t_CKDUR
)delay
->getDelay();
21097 t_CKDUR max
= GET_NEXT_DUR(value
);
21098 delay
->set( val
, (long)(max
+1.5) );
21101 UGEN_CGET
DelayL_cget_delay( t_CKTIME now
, void * data
, void * value
)
21103 SET_NEXT_DUR( value
, (t_CKDUR
)((DelayL
*)data
)->getDelay() );
21106 UGEN_CGET
DelayL_cget_max( t_CKTIME now
, void * data
, void * value
)
21108 SET_NEXT_DUR( value
, (t_CKDUR
)((DelayL
*)data
)->length
-1.0 );
21113 UGEN_CTOR
Echo_ctor( t_CKTIME now
)
21115 return new Echo( Stk::sampleRate() / 2.0 );
21118 UGEN_DTOR
Echo_dtor( t_CKTIME now
, void * data
)
21120 delete (Echo
*)data
;
21123 UGEN_TICK
Echo_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21125 *out
= (SAMPLE
)((Echo
*)data
)->tick( in
);
21129 UGEN_PMSG
Echo_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21134 UGEN_CTRL
Echo_ctrl_delay( t_CKTIME now
, void * data
, void * value
)
21136 ((Echo
*)data
)->setDelay( GET_NEXT_DUR(value
) );
21139 UGEN_CTRL
Echo_ctrl_max( t_CKTIME now
, void * data
, void * value
)
21141 ((Echo
*)data
)->set( GET_NEXT_DUR(value
) );
21144 UGEN_CTRL
Echo_ctrl_mix( t_CKTIME now
, void * data
, void * value
)
21146 ((Echo
*)data
)->setEffectMix( GET_NEXT_FLOAT(value
) );
21149 UGEN_CGET
Echo_cget_delay( t_CKTIME now
, void * data
, void * value
)
21151 SET_NEXT_DUR( value
, (t_CKDUR
)((Echo
*)data
)->getDelay() );
21154 UGEN_CGET
Echo_cget_max( t_CKTIME now
, void * data
, void * value
)
21156 SET_NEXT_DUR( value
, (t_CKDUR
)((Echo
*)data
)->length
);
21159 UGEN_CGET
Echo_cget_mix( t_CKTIME now
, void * data
, void * value
)
21161 SET_NEXT_FLOAT( value
, (t_CKFLOAT
)((Echo
*)data
)->effectMix
);
21166 //-----------------------------------------------------------------------------
21167 // name: Envelope - import
21169 //-----------------------------------------------------------------------------
21170 UGEN_CTOR
Envelope_ctor( t_CKTIME now
)
21172 return new Envelope
;
21175 UGEN_DTOR
Envelope_dtor( t_CKTIME now
, void * data
)
21177 delete (Envelope
*)data
;
21180 UGEN_TICK
Envelope_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21182 Envelope
* d
= (Envelope
*)data
;
21183 *out
= in
* d
->tick();
21187 UGEN_PMSG
Envelope_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21192 UGEN_CTRL
Envelope_ctrl_time( t_CKTIME now
, void * data
, void * value
)
21194 Envelope
* d
= (Envelope
*)data
;
21195 d
->setTime( GET_NEXT_FLOAT(value
) );
21198 UGEN_CTRL
Envelope_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
21200 Envelope
* d
= (Envelope
*)data
;
21201 d
->setRate( GET_NEXT_FLOAT(value
) );
21204 UGEN_CTRL
Envelope_ctrl_target( t_CKTIME now
, void * data
, void * value
)
21206 Envelope
* d
= (Envelope
*)data
;
21207 d
->setTarget( GET_NEXT_FLOAT(value
) );
21210 UGEN_CTRL
Envelope_ctrl_value( t_CKTIME now
, void * data
, void * value
)
21212 Envelope
* d
= (Envelope
*)data
;
21213 d
->setValue( GET_NEXT_FLOAT(value
) );
21216 UGEN_CTRL
Envelope_ctrl_keyOn( t_CKTIME now
, void * data
, void * value
)
21218 Envelope
* d
= (Envelope
*)data
;
21219 if( GET_NEXT_INT(value
) )
21225 UGEN_CTRL
Envelope_ctrl_keyOff( t_CKTIME now
, void * data
, void * value
)
21227 Envelope
* d
= (Envelope
*)data
;
21228 if( !GET_NEXT_INT(value
) )
21234 UGEN_CTRL
Envelope_cget_target( t_CKTIME now
, void * data
, void * value
)
21236 Envelope
* d
= (Envelope
*)data
;
21237 SET_NEXT_FLOAT( value
, d
->target
);
21240 UGEN_CTRL
Envelope_cget_value( t_CKTIME now
, void * data
, void * value
)
21242 Envelope
* d
= (Envelope
*)data
;
21243 SET_NEXT_FLOAT( value
, d
->value
);
21246 UGEN_CTRL
Envelope_cget_rate( t_CKTIME now
, void * data
, void * value
)
21248 Envelope
* d
= (Envelope
*)data
;
21249 SET_NEXT_FLOAT( value
, d
->rate
);
21252 UGEN_CTRL
Envelope_cget_time( t_CKTIME now
, void * data
, void * value
)
21254 Envelope
* d
= (Envelope
*)data
;
21255 SET_NEXT_FLOAT( value
, 1.0 / ( d
->rate
* Stk::sampleRate() ) );
21258 //-----------------------------------------------------------------------------
21259 // name: ADSR - import
21261 //-----------------------------------------------------------------------------
21262 UGEN_CTOR
ADSR_ctor( t_CKTIME now
)
21267 UGEN_DTOR
ADSR_dtor( t_CKTIME now
, void * data
)
21269 delete (ADSR
*)data
;
21272 UGEN_TICK
ADSR_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21274 ADSR
* d
= (ADSR
*)data
;
21275 *out
= in
* d
->tick();
21279 UGEN_PMSG
ADSR_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21284 UGEN_CTRL
ADSR_ctrl_attackTime( t_CKTIME now
, void * data
, void * value
)
21286 ADSR
* d
= (ADSR
*)data
;
21287 d
->setAttackTime( GET_NEXT_FLOAT(value
) );
21290 UGEN_CTRL
ADSR_ctrl_attackRate( t_CKTIME now
, void * data
, void * value
)
21292 ADSR
* d
= (ADSR
*)data
;
21293 d
->setAttackRate( GET_NEXT_FLOAT(value
) );
21296 UGEN_CTRL
ADSR_ctrl_decayTime( t_CKTIME now
, void * data
, void * value
)
21298 ADSR
* d
= (ADSR
*)data
;
21299 d
->setDecayTime( GET_NEXT_FLOAT(value
) );
21302 UGEN_CTRL
ADSR_ctrl_decayRate( t_CKTIME now
, void * data
, void * value
)
21304 ADSR
* d
= (ADSR
*)data
;
21305 d
->setDecayRate( GET_NEXT_FLOAT(value
) );
21308 UGEN_CTRL
ADSR_ctrl_sustainLevel( t_CKTIME now
, void * data
, void * value
)
21310 ADSR
* d
= (ADSR
*)data
;
21311 d
->setSustainLevel( GET_NEXT_FLOAT(value
) );
21314 UGEN_CTRL
ADSR_ctrl_releaseTime( t_CKTIME now
, void * data
, void * value
)
21316 ADSR
* d
= (ADSR
*)data
;
21317 d
->setReleaseTime( GET_NEXT_FLOAT(value
) );
21320 UGEN_CTRL
ADSR_ctrl_releaseRate( t_CKTIME now
, void * data
, void * value
)
21322 ADSR
* d
= (ADSR
*)data
;
21323 d
->setReleaseRate( GET_NEXT_FLOAT(value
) );
21326 UGEN_CTRL
ADSR_ctrl_target( t_CKTIME now
, void * data
, void * value
)
21328 ADSR
* d
= (ADSR
*)data
;
21329 d
->setTarget( GET_NEXT_FLOAT(value
) );
21332 UGEN_CTRL
ADSR_ctrl_value( t_CKTIME now
, void * data
, void * value
)
21334 ADSR
* d
= (ADSR
*)data
;
21335 d
->setValue( GET_NEXT_FLOAT(value
) );
21338 UGEN_CTRL
ADSR_ctrl_keyOn( t_CKTIME now
, void * data
, void * value
)
21340 ADSR
* d
= (ADSR
*)data
;
21341 if( GET_NEXT_INT(value
) )
21347 UGEN_CTRL
ADSR_ctrl_keyOff( t_CKTIME now
, void * data
, void * value
)
21349 ADSR
* d
= (ADSR
*)data
;
21350 if( !GET_NEXT_INT(value
) )
21356 UGEN_CTRL
ADSR_cget_attackRate( t_CKTIME now
, void * data
, void * value
)
21358 ADSR
* d
= (ADSR
*)data
;
21359 SET_NEXT_FLOAT( value
, d
->attackRate
);
21362 UGEN_CTRL
ADSR_cget_decayRate( t_CKTIME now
, void * data
, void * value
)
21364 ADSR
* d
= (ADSR
*)data
;
21365 SET_NEXT_FLOAT( value
, d
->decayRate
);
21368 UGEN_CTRL
ADSR_cget_sustainLevel( t_CKTIME now
, void * data
, void * value
)
21370 ADSR
* d
= (ADSR
*)data
;
21371 SET_NEXT_FLOAT( value
, d
->sustainLevel
);
21374 UGEN_CTRL
ADSR_cget_releaseRate( t_CKTIME now
, void * data
, void * value
)
21376 ADSR
* d
= (ADSR
*)data
;
21377 SET_NEXT_FLOAT( value
, d
->releaseRate
);
21380 UGEN_CTRL
ADSR_cget_target( t_CKTIME now
, void * data
, void * value
)
21382 ADSR
* d
= (ADSR
*)data
;
21383 SET_NEXT_FLOAT( value
, d
->target
);
21386 UGEN_CTRL
ADSR_cget_value( t_CKTIME now
, void * data
, void * value
)
21388 ADSR
* d
= (ADSR
*)data
;
21389 SET_NEXT_FLOAT( value
, d
->value
);
21392 UGEN_CTRL
ADSR_cget_state( t_CKTIME now
, void * data
, void * value
)
21394 ADSR
* d
= (ADSR
*)data
;
21395 SET_NEXT_INT( value
, d
->state
);
21400 UGEN_CTOR
Filter_ctor( t_CKTIME now
)
21405 UGEN_DTOR
Filter_dtor( t_CKTIME now
, void * data
)
21407 delete (Filter
*)data
;
21410 UGEN_TICK
Filter_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21412 Filter
* d
= (Filter
*)data
;
21413 *out
= d
->tick( in
);
21417 UGEN_PMSG
Filter_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21423 UGEN_CTRL
Filter_ctrl_coefs( t_CKTIME now
, void * data
, void * value
)
21425 Filter
* d
= (Filter
*)data
;
21426 fprintf(stderr
,"Filter.coefs :: not implemented\n");
21431 UGEN_CTOR
OnePole_ctor ( t_CKTIME now
)
21433 return new OnePole();
21436 UGEN_DTOR
OnePole_dtor ( t_CKTIME now
, void * data
)
21438 delete (OnePole
*)data
;
21441 UGEN_TICK
OnePole_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21443 OnePole
* m
= (OnePole
*)data
;
21444 *out
= m
->tick( in
);
21448 UGEN_PMSG
OnePole_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21453 UGEN_CTRL
OnePole_ctrl_a1( t_CKTIME now
, void * data
, void * value
)
21455 OnePole
* filter
= (OnePole
*)data
;
21456 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21457 filter
->setA1( f
);
21460 UGEN_CTRL
OnePole_ctrl_b0( t_CKTIME now
, void * data
, void * value
)
21462 OnePole
* filter
= (OnePole
*)data
;
21463 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21464 filter
->setB0( f
);
21467 UGEN_CTRL
OnePole_ctrl_pole( t_CKTIME now
, void * data
, void * value
)
21469 OnePole
* filter
= (OnePole
*)data
;
21470 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21471 filter
->setPole( f
);
21475 UGEN_CGET
OnePole_cget_a1( t_CKTIME now
, void * data
, void * value
)
21477 OnePole
* filter
= (OnePole
*)data
;
21478 SET_NEXT_FLOAT( value
, filter
->a
[1] );
21481 UGEN_CGET
OnePole_cget_b0( t_CKTIME now
, void * data
, void * value
)
21483 OnePole
* filter
= (OnePole
*)data
;
21484 SET_NEXT_FLOAT( value
, filter
->b
[0] );
21487 UGEN_CGET
OnePole_cget_pole( t_CKTIME now
, void * data
, void * value
)
21489 OnePole
* filter
= (OnePole
*)data
;
21490 SET_NEXT_FLOAT( value
, -filter
->a
[1] );
21494 //TwoPole functions
21496 UGEN_CTOR
TwoPole_ctor ( t_CKTIME now
)
21498 return new TwoPole();
21501 UGEN_DTOR
TwoPole_dtor ( t_CKTIME now
, void * data
)
21503 delete (TwoPole
*)data
;
21506 UGEN_TICK
TwoPole_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21508 TwoPole
* m
= (TwoPole
*)data
;
21509 *out
= m
->tick( in
);
21513 UGEN_PMSG
TwoPole_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21518 UGEN_CTRL
TwoPole_ctrl_a1( t_CKTIME now
, void * data
, void * value
)
21520 TwoPole
* filter
= (TwoPole
*)data
;
21521 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21522 filter
->setA1( f
);
21525 UGEN_CTRL
TwoPole_ctrl_a2( t_CKTIME now
, void * data
, void * value
)
21527 TwoPole
* filter
= (TwoPole
*)data
;
21528 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21529 filter
->setA2( f
);
21532 UGEN_CTRL
TwoPole_ctrl_b0( t_CKTIME now
, void * data
, void * value
)
21534 TwoPole
* filter
= (TwoPole
*)data
;
21535 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21536 filter
->setB0( f
);
21539 UGEN_CTRL
TwoPole_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
21541 TwoPole
* filter
= (TwoPole
*)data
;
21542 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21543 filter
->ck_setResFreq( f
);
21546 UGEN_CTRL
TwoPole_ctrl_radius( t_CKTIME now
, void * data
, void * value
)
21548 TwoPole
* filter
= (TwoPole
*)data
;
21549 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21550 filter
->ck_setResRad( f
);
21553 UGEN_CTRL
TwoPole_ctrl_norm( t_CKTIME now
, void * data
, void * value
)
21555 TwoPole
* filter
= (TwoPole
*)data
;
21556 bool b
= ( GET_CK_INT(value
) != 0 );
21557 filter
->ck_setResNorm( b
);
21561 UGEN_CGET
TwoPole_cget_a1( t_CKTIME now
, void * data
, void * value
)
21563 TwoPole
* filter
= (TwoPole
*)data
;
21564 SET_NEXT_FLOAT( value
, filter
->a
[1] );
21567 UGEN_CGET
TwoPole_cget_a2( t_CKTIME now
, void * data
, void * value
)
21569 TwoPole
* filter
= (TwoPole
*)data
;
21570 SET_NEXT_FLOAT( value
, filter
->a
[2] );
21573 UGEN_CGET
TwoPole_cget_b0( t_CKTIME now
, void * data
, void * value
)
21575 TwoPole
* filter
= (TwoPole
*)data
;
21576 SET_NEXT_FLOAT( value
, filter
->b
[0] );
21579 UGEN_CGET
TwoPole_cget_freq( t_CKTIME now
, void * data
, void * value
)
21581 TwoPole
* filter
= (TwoPole
*)data
;
21582 SET_NEXT_FLOAT( value
, filter
->m_resFreq
);
21585 UGEN_CGET
TwoPole_cget_radius( t_CKTIME now
, void * data
, void * value
)
21587 TwoPole
* filter
= (TwoPole
*)data
;
21588 SET_NEXT_FLOAT( value
, filter
->m_resRad
);
21591 UGEN_CGET
TwoPole_cget_norm( t_CKTIME now
, void * data
, void * value
)
21593 TwoPole
* filter
= (TwoPole
*)data
;
21594 SET_NEXT_INT( value
, filter
->m_resNorm
);
21600 //OneZero functions
21602 UGEN_CTOR
OneZero_ctor ( t_CKTIME now
)
21604 return new OneZero();
21607 UGEN_DTOR
OneZero_dtor ( t_CKTIME now
, void * data
)
21609 delete (OneZero
*)data
;
21612 UGEN_TICK
OneZero_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21614 OneZero
* m
= (OneZero
*)data
;
21615 *out
= m
->tick( in
);
21619 UGEN_PMSG
OneZero_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21624 UGEN_CTRL
OneZero_ctrl_zero( t_CKTIME now
, void * data
, void * value
)
21626 OneZero
* filter
= (OneZero
*)data
;
21627 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21628 filter
->setZero( f
);
21631 UGEN_CTRL
OneZero_ctrl_b0( t_CKTIME now
, void * data
, void * value
)
21633 OneZero
* filter
= (OneZero
*)data
;
21634 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21635 filter
->setB0( f
);
21638 UGEN_CTRL
OneZero_ctrl_b1( t_CKTIME now
, void * data
, void * value
)
21640 OneZero
* filter
= (OneZero
*)data
;
21641 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21642 filter
->setB1( f
);
21645 UGEN_CGET
OneZero_cget_zero( t_CKTIME now
, void * data
, void * value
)
21647 OneZero
* filter
= (OneZero
*)data
;
21648 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21649 double zeeroo
= ( filter
->b
[0] == 0 ) ? 0 : -filter
->b
[1] / filter
->b
[0];
21650 SET_NEXT_FLOAT( value
, zeeroo
);
21653 UGEN_CGET
OneZero_cget_b0( t_CKTIME now
, void * data
, void * value
)
21655 OneZero
* filter
= (OneZero
*)data
;
21656 SET_NEXT_FLOAT( value
, filter
->b
[0] );
21659 UGEN_CGET
OneZero_cget_b1( t_CKTIME now
, void * data
, void * value
)
21662 OneZero
* filter
= (OneZero
*)data
;
21663 SET_NEXT_FLOAT( value
, filter
->b
[1] );
21668 //TwoZero functions
21670 UGEN_CTOR
TwoZero_ctor ( t_CKTIME now
)
21672 return new TwoZero();
21675 UGEN_DTOR
TwoZero_dtor ( t_CKTIME now
, void * data
)
21677 delete (TwoZero
*)data
;
21680 UGEN_TICK
TwoZero_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21682 TwoZero
* m
= (TwoZero
*)data
;
21683 *out
= m
->tick( in
);
21687 UGEN_PMSG
TwoZero_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21692 UGEN_CTRL
TwoZero_ctrl_b0( t_CKTIME now
, void * data
, void * value
)
21694 TwoZero
* filter
= (TwoZero
*)data
;
21695 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21696 filter
->setB0( f
);
21699 UGEN_CTRL
TwoZero_ctrl_b1( t_CKTIME now
, void * data
, void * value
)
21701 TwoZero
* filter
= (TwoZero
*)data
;
21702 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21703 filter
->setB1( f
);
21706 UGEN_CTRL
TwoZero_ctrl_b2( t_CKTIME now
, void * data
, void * value
)
21708 TwoZero
* filter
= (TwoZero
*)data
;
21709 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21710 filter
->setB2( f
);
21714 UGEN_CTRL
TwoZero_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
21716 TwoZero
* filter
= (TwoZero
*)data
;
21717 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21718 filter
->ck_setNotchFreq( f
);
21722 UGEN_CTRL
TwoZero_ctrl_radius( t_CKTIME now
, void * data
, void * value
)
21724 TwoZero
* filter
= (TwoZero
*)data
;
21725 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21726 filter
->ck_setNotchRad( f
);
21730 UGEN_CGET
TwoZero_cget_b0( t_CKTIME now
, void * data
, void * value
)
21732 TwoZero
* filter
= (TwoZero
*)data
;
21733 SET_NEXT_FLOAT( value
, filter
->b
[0] );
21736 UGEN_CGET
TwoZero_cget_b1( t_CKTIME now
, void * data
, void * value
)
21738 TwoZero
* filter
= (TwoZero
*)data
;
21739 SET_NEXT_FLOAT( value
, filter
->b
[1] );
21742 UGEN_CGET
TwoZero_cget_b2( t_CKTIME now
, void * data
, void * value
)
21744 TwoZero
* filter
= (TwoZero
*)data
;
21745 SET_NEXT_FLOAT( value
, filter
->b
[2] );
21749 UGEN_CGET
TwoZero_cget_freq( t_CKTIME now
, void * data
, void * value
)
21751 TwoZero
* filter
= (TwoZero
*)data
;
21752 SET_NEXT_FLOAT( value
, filter
->m_notchFreq
);
21756 UGEN_CGET
TwoZero_cget_radius( t_CKTIME now
, void * data
, void * value
)
21758 TwoZero
* filter
= (TwoZero
*)data
;
21759 SET_NEXT_FLOAT( value
, filter
->m_notchRad
);
21764 //PoleZero functions
21766 UGEN_CTOR
PoleZero_ctor ( t_CKTIME now
)
21768 return new PoleZero();
21771 UGEN_DTOR
PoleZero_dtor ( t_CKTIME now
, void * data
)
21773 delete (PoleZero
*)data
;
21776 UGEN_TICK
PoleZero_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21778 PoleZero
* m
= (PoleZero
*)data
;
21779 *out
= m
->tick( in
);
21783 UGEN_PMSG
PoleZero_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21789 UGEN_CTRL
PoleZero_ctrl_a1( t_CKTIME now
, void * data
, void * value
)
21791 PoleZero
* filter
= (PoleZero
*)data
;
21792 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21793 filter
->setA1( f
);
21796 UGEN_CTRL
PoleZero_ctrl_b0( t_CKTIME now
, void * data
, void * value
)
21798 PoleZero
* filter
= (PoleZero
*)data
;
21799 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21800 filter
->setB0( f
);
21803 UGEN_CTRL
PoleZero_ctrl_b1( t_CKTIME now
, void * data
, void * value
)
21805 PoleZero
* filter
= (PoleZero
*)data
;
21806 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21807 filter
->setB1( f
);
21810 UGEN_CTRL
PoleZero_ctrl_allpass( t_CKTIME now
, void * data
, void * value
)
21812 PoleZero
* filter
= (PoleZero
*)data
;
21813 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21814 filter
->setAllpass( f
);
21817 UGEN_CTRL
PoleZero_ctrl_blockZero( t_CKTIME now
, void * data
, void * value
)
21819 PoleZero
* filter
= (PoleZero
*)data
;
21820 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21821 filter
->setBlockZero( f
);
21824 UGEN_CGET
PoleZero_cget_a1( t_CKTIME now
, void * data
, void * value
)
21826 PoleZero
* filter
= (PoleZero
*)data
;
21827 SET_NEXT_FLOAT ( value
, filter
->a
[1] );
21830 UGEN_CGET
PoleZero_cget_b0( t_CKTIME now
, void * data
, void * value
)
21832 PoleZero
* filter
= (PoleZero
*)data
;
21833 SET_NEXT_FLOAT ( value
, filter
->b
[0] );
21836 UGEN_CGET
PoleZero_cget_b1( t_CKTIME now
, void * data
, void * value
)
21838 PoleZero
* filter
= (PoleZero
*)data
;
21839 SET_NEXT_FLOAT ( value
, filter
->b
[1] );
21842 UGEN_CGET
PoleZero_cget_allpass( t_CKTIME now
, void * data
, void * value
)
21844 PoleZero
* filter
= (PoleZero
*)data
;
21845 SET_NEXT_FLOAT ( value
, filter
->b
[0] );
21848 UGEN_CGET
PoleZero_cget_blockZero( t_CKTIME now
, void * data
, void * value
)
21850 PoleZero
* filter
= (PoleZero
*)data
;
21851 SET_NEXT_FLOAT ( value
, -filter
->a
[1] );
21858 UGEN_CTOR
FM_ctor ( t_CKTIME now
)
21860 // return new FM(4);
21861 fprintf(stderr
,"error : FM is virtual - not for use! \n");
21865 UGEN_DTOR
FM_dtor ( t_CKTIME now
, void * data
)
21867 // delete (FM *)data;
21868 fprintf(stderr
,"error : FM is virtual!\n");
21871 UGEN_TICK
FM_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21873 FM
* m
= (FM
*)data
;
21874 // *out = m->tick();
21875 fprintf(stderr
,"error : FM tick is virtual\n");
21879 UGEN_PMSG
FM_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21884 UGEN_CTRL
FM_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
21886 FM
* fm
= (FM
*)data
;
21887 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21888 fm
->setFrequency( f
);
21893 UGEN_CTRL
FM_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
21895 FM
* fm
= (FM
*)data
;
21896 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21900 UGEN_CTRL
FM_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
21902 FM
* fm
= (FM
*)data
;
21903 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21907 UGEN_CTRL
FM_ctrl_modDepth( t_CKTIME now
, void * data
, void * value
)
21909 FM
* fm
= (FM
*)data
;
21910 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21911 fm
->setModulationDepth( f
);
21914 UGEN_CTRL
FM_ctrl_modSpeed( t_CKTIME now
, void * data
, void * value
)
21916 FM
* fm
= (FM
*)data
;
21917 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21918 fm
->setModulationSpeed( f
);
21921 UGEN_CTRL
FM_ctrl_control1( t_CKTIME now
, void * data
, void * value
)
21923 FM
* fm
= (FM
*)data
;
21924 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21925 fm
->setControl1( f
);
21928 UGEN_CTRL
FM_ctrl_control2( t_CKTIME now
, void * data
, void * value
)
21930 FM
* fm
= (FM
*)data
;
21931 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21932 fm
->setControl2( f
);
21935 UGEN_CTRL
FM_ctrl_afterTouch( t_CKTIME now
, void * data
, void * value
)
21937 FM
* fm
= (FM
*)data
;
21938 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21939 fm
->controlChange( __SK_AfterTouch_Cont_
, f
* 128.0 );
21942 UGEN_CTRL
FM_cget_freq( t_CKTIME now
, void * data
, void * value
)
21944 FM
* fm
= (FM
*)data
;
21945 SET_NEXT_FLOAT ( value
, fm
->baseFrequency
);
21948 //let's skip the controlchange members for now...
21951 //BeeThree functions
21953 UGEN_CTOR
BeeThree_ctor ( t_CKTIME now
)
21955 return new BeeThree();
21958 UGEN_DTOR
BeeThree_dtor ( t_CKTIME now
, void * data
)
21960 delete (BeeThree
*)data
;
21963 UGEN_TICK
BeeThree_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21965 BeeThree
* m
= (BeeThree
*)data
;
21970 UGEN_PMSG
BeeThree_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
21975 UGEN_CTRL
BeeThree_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
21977 BeeThree
* bee
= (BeeThree
*)data
;
21978 t_CKFLOAT f
= GET_CK_FLOAT(value
);
21983 //FMVoices functions
21985 UGEN_CTOR
FMVoices_ctor ( t_CKTIME now
)
21987 return new FMVoices();
21990 UGEN_DTOR
FMVoices_dtor ( t_CKTIME now
, void * data
)
21992 delete (FMVoices
*)data
;
21995 UGEN_TICK
FMVoices_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
21997 FMVoices
* m
= (FMVoices
*)data
;
22002 UGEN_PMSG
FMVoices_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22007 UGEN_CTRL
FMVoices_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22009 FMVoices
* voc
= (FMVoices
*)data
;
22010 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22014 UGEN_CTRL
FMVoices_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22016 FMVoices
* voc
= (FMVoices
*)data
;
22017 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22018 voc
->setFrequency( f
);
22021 UGEN_CTRL
FMVoices_ctrl_vowel( t_CKTIME now
, void * data
, void * value
)
22023 FMVoices
* voc
= (FMVoices
*)data
;
22024 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22025 voc
->controlChange( __SK_Breath_
, f
* 128.0 );
22028 UGEN_CTRL
FMVoices_ctrl_spectralTilt( t_CKTIME now
, void * data
, void * value
)
22030 FMVoices
* voc
= (FMVoices
*)data
;
22031 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22032 voc
->controlChange( __SK_FootControl_
, f
* 128.0);
22035 UGEN_CTRL
FMVoices_ctrl_lfoSpeed( t_CKTIME now
, void * data
, void * value
)
22037 FMVoices
* voc
= (FMVoices
*)data
;
22038 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22039 voc
->controlChange( __SK_ModFrequency_
, f
* 128.0);
22042 UGEN_CTRL
FMVoices_ctrl_lfoDepth( t_CKTIME now
, void * data
, void * value
)
22044 FMVoices
* voc
= (FMVoices
*)data
;
22045 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22046 voc
->controlChange( __SK_ModWheel_
, f
* 128.0);
22049 UGEN_CTRL
FMVoices_ctrl_adsrTarget( t_CKTIME now
, void * data
, void * value
)
22051 FMVoices
* voc
= (FMVoices
*)data
;
22052 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22053 voc
->controlChange( __SK_AfterTouch_Cont_
, f
* 128.0);
22057 UGEN_CGET
FMVoices_cget_freq( t_CKTIME now
, void * data
, void * value
)
22059 FMVoices
* voc
= (FMVoices
*)data
;
22060 SET_NEXT_FLOAT ( value
, voc
->baseFrequency
) ;
22064 //HevyMetl functions
22066 UGEN_CTOR
HevyMetl_ctor ( t_CKTIME now
)
22068 return new HevyMetl();
22071 UGEN_DTOR
HevyMetl_dtor ( t_CKTIME now
, void * data
)
22073 delete (HevyMetl
*)data
;
22076 UGEN_TICK
HevyMetl_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22078 HevyMetl
* m
= (HevyMetl
*)data
;
22083 UGEN_PMSG
HevyMetl_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22088 UGEN_CTRL
HevyMetl_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22090 HevyMetl
* hevy
= (HevyMetl
*)data
;
22091 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22096 //PercFlut functions
22098 UGEN_CTOR
PercFlut_ctor ( t_CKTIME now
)
22100 return new PercFlut();
22103 UGEN_DTOR
PercFlut_dtor ( t_CKTIME now
, void * data
)
22105 delete (PercFlut
*)data
;
22108 UGEN_TICK
PercFlut_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22110 PercFlut
* m
= (PercFlut
*)data
;
22115 UGEN_PMSG
PercFlut_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22120 UGEN_CTRL
PercFlut_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22122 PercFlut
* perc
= (PercFlut
*)data
;
22123 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22127 UGEN_CTRL
PercFlut_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22129 PercFlut
* perc
= (PercFlut
*)data
;
22130 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22131 perc
->setFrequency( f
);
22134 UGEN_CGET
PercFlut_cget_freq( t_CKTIME now
, void * data
, void * value
)
22136 PercFlut
* perc
= (PercFlut
*)data
;
22137 SET_NEXT_FLOAT ( value
, perc
->baseFrequency
) ;
22143 UGEN_CTOR
Rhodey_ctor ( t_CKTIME now
)
22145 return new Rhodey();
22148 UGEN_DTOR
Rhodey_dtor ( t_CKTIME now
, void * data
)
22150 delete (Rhodey
*)data
;
22153 UGEN_TICK
Rhodey_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22155 Rhodey
* m
= (Rhodey
*)data
;
22160 UGEN_PMSG
Rhodey_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22165 UGEN_CTRL
Rhodey_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22167 Rhodey
* rhod
= (Rhodey
*)data
;
22168 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22169 rhod
->setFrequency( f
);
22172 UGEN_CGET
Rhodey_cget_freq( t_CKTIME now
, void * data
, void * value
)
22174 Rhodey
* rhod
= (Rhodey
*)data
;
22175 SET_NEXT_FLOAT ( value
, rhod
->baseFrequency
* 0.5 ) ;
22179 UGEN_CTRL
Rhodey_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22181 Rhodey
* rhod
= (Rhodey
*)data
;
22182 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22186 UGEN_CTRL
Rhodey_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
22188 Rhodey
* rhod
= (Rhodey
*)data
;
22189 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22190 rhod
->noteOff( f
);
22193 //TubeBell functions
22195 UGEN_CTOR
TubeBell_ctor ( t_CKTIME now
)
22197 return new TubeBell();
22200 UGEN_DTOR
TubeBell_dtor ( t_CKTIME now
, void * data
)
22202 delete (TubeBell
*)data
;
22205 UGEN_TICK
TubeBell_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22207 TubeBell
* m
= (TubeBell
*)data
;
22212 UGEN_PMSG
TubeBell_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22217 UGEN_CTRL
TubeBell_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22219 TubeBell
* tube
= (TubeBell
*)data
;
22220 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22224 UGEN_CTRL
TubeBell_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22226 TubeBell
* tube
= (TubeBell
*)data
;
22227 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22228 tube
->setFrequency( f
);
22232 UGEN_CGET
TubeBell_cget_freq( t_CKTIME now
, void * data
, void * value
)
22234 TubeBell
* tube
= (TubeBell
*)data
;
22235 SET_NEXT_FLOAT( value
, tube
->baseFrequency
);
22242 UGEN_CTOR
Wurley_ctor ( t_CKTIME now
)
22244 return new Wurley();
22247 UGEN_DTOR
Wurley_dtor ( t_CKTIME now
, void * data
)
22249 delete (Wurley
*)data
;
22252 UGEN_TICK
Wurley_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22254 Wurley
* m
= (Wurley
*)data
;
22259 UGEN_PMSG
Wurley_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22264 UGEN_CTRL
Wurley_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22266 Wurley
* wurl
= (Wurley
*)data
;
22267 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22268 wurl
->setFrequency( f
);
22272 UGEN_CTRL
Wurley_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22274 Wurley
* wurl
= (Wurley
*)data
;
22275 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22279 UGEN_CTRL
Wurley_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
22281 Wurley
* wurl
= (Wurley
*)data
;
22282 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22283 wurl
->noteOff( f
);
22286 UGEN_CGET
Wurley_cget_freq( t_CKTIME now
, void * data
, void * value
)
22288 Wurley
* wurl
= (Wurley
*)data
;
22289 SET_NEXT_FLOAT( value
, wurl
->baseFrequency
);
22292 //FormSwep functions
22294 UGEN_CTOR
FormSwep_ctor ( t_CKTIME now
)
22296 return new FormSwep();
22299 UGEN_DTOR
FormSwep_dtor ( t_CKTIME now
, void * data
)
22301 delete (FormSwep
*)data
;
22304 UGEN_TICK
FormSwep_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22306 FormSwep
* m
= (FormSwep
*)data
;
22307 *out
= m
->tick(in
);
22311 UGEN_PMSG
FormSwep_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22316 //FormSwep requires multiple arguments
22317 //to most of its parameters.
22321 UGEN_CTOR
JCRev_ctor( t_CKTIME now
)
22323 return new JCRev( 4.0f
);
22326 UGEN_DTOR
JCRev_dtor( t_CKTIME now
, void * data
)
22328 delete (JCRev
*)data
;
22331 UGEN_TICK
JCRev_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22333 JCRev
* j
= (JCRev
*)data
;
22334 *out
= j
->tick( in
);
22338 UGEN_PMSG
JCRev_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22343 UGEN_CTRL
JCRev_ctrl_mix( t_CKTIME now
, void * data
, void * value
)
22345 JCRev
* j
= (JCRev
*)data
;
22346 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22347 j
->setEffectMix( f
);
22350 UGEN_CGET
JCRev_cget_mix( t_CKTIME now
, void * data
, void * value
)
22352 JCRev
* j
= (JCRev
*)data
;
22353 SET_NEXT_FLOAT ( value
, j
->effectMix
);
22357 UGEN_CTOR
Mandolin_ctor ( t_CKTIME now
)
22359 return new Mandolin( 50.0f
);
22362 UGEN_DTOR
Mandolin_dtor ( t_CKTIME now
, void * data
)
22364 delete (Mandolin
*)data
;
22367 UGEN_TICK
Mandolin_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22369 Mandolin
* m
= (Mandolin
*)data
;
22374 UGEN_PMSG
Mandolin_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22379 UGEN_CTRL
Mandolin_ctrl_pluck( t_CKTIME now
, void * data
, void * value
)
22381 Mandolin
* m
= (Mandolin
*)data
;
22382 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22386 UGEN_CTRL
Mandolin_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22388 Mandolin
* m
= (Mandolin
*)data
;
22389 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22390 m
->setFrequency( f
);
22394 UGEN_CTRL
Mandolin_ctrl_pluckPos( t_CKTIME now
, void * data
, void * value
)
22396 Mandolin
* m
= (Mandolin
*)data
;
22397 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22398 m
->setPluckPosition( f
);
22401 UGEN_CTRL
Mandolin_ctrl_bodySize( t_CKTIME now
, void * data
, void * value
)
22403 Mandolin
* m
= (Mandolin
*)data
;
22404 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22405 m
->setBodySize( f
* 2.0 );
22408 UGEN_CTRL
Mandolin_ctrl_stringDamping( t_CKTIME now
, void * data
, void * value
)
22410 Mandolin
* m
= (Mandolin
*)data
;
22411 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22412 m
->setBaseLoopGain( 0.97f
+ f
* 0.03f
);
22415 UGEN_CTRL
Mandolin_ctrl_stringDetune( t_CKTIME now
, void * data
, void * value
)
22417 Mandolin
* m
= (Mandolin
*)data
;
22418 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22419 m
->setDetune( 1.0f
- 0.1f
* f
);
22422 UGEN_CTRL
Mandolin_ctrl_afterTouch( t_CKTIME now
, void * data
, void * value
)
22424 Mandolin
* m
= (Mandolin
*)data
;
22425 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22426 //not sure what this does in stk version so we'll just call controlChange
22427 m
->controlChange( __SK_AfterTouch_Cont_
, f
* 128.0 );
22432 UGEN_CGET
Mandolin_cget_freq( t_CKTIME now
, void * data
, void * value
)
22434 Mandolin
* m
= (Mandolin
*)data
;
22435 SET_NEXT_FLOAT ( value
, m
->lastFrequency
);
22438 UGEN_CGET
Mandolin_cget_pluckPos( t_CKTIME now
, void * data
, void * value
)
22440 Mandolin
* m
= (Mandolin
*)data
;
22441 SET_NEXT_FLOAT ( value
, m
->pluckPosition
);
22444 UGEN_CGET
Mandolin_cget_bodySize( t_CKTIME now
, void * data
, void * value
)
22446 Mandolin
* m
= (Mandolin
*)data
;
22447 SET_NEXT_FLOAT ( value
, m
->m_bodySize
);
22450 UGEN_CGET
Mandolin_cget_stringDamping( t_CKTIME now
, void * data
, void * value
)
22452 Mandolin
* m
= (Mandolin
*)data
;
22453 SET_NEXT_FLOAT ( value
, m
->m_stringDamping
);
22456 UGEN_CGET
Mandolin_cget_stringDetune( t_CKTIME now
, void * data
, void * value
)
22458 Mandolin
* m
= (Mandolin
*)data
;
22459 SET_NEXT_FLOAT ( value
, m
->m_stringDetune
);
22463 UGEN_CTOR
Modulate_ctor( t_CKTIME now
)
22465 return new Modulate( );
22468 UGEN_DTOR
Modulate_dtor( t_CKTIME now
, void * data
)
22470 delete (Modulate
*)data
;
22473 UGEN_TICK
Modulate_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22475 Modulate
* j
= (Modulate
*)data
;
22480 UGEN_PMSG
Modulate_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22485 UGEN_CTRL
Modulate_ctrl_vibratoRate( t_CKTIME now
, void * data
, void * value
)
22487 Modulate
* j
= (Modulate
*)data
;
22488 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22489 j
->setVibratoRate( f
);
22492 UGEN_CTRL
Modulate_ctrl_vibratoGain( t_CKTIME now
, void * data
, void * value
)
22494 Modulate
* j
= (Modulate
*)data
;
22495 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22496 j
->setVibratoGain( f
);
22499 UGEN_CTRL
Modulate_ctrl_randomGain( t_CKTIME now
, void * data
, void * value
)
22501 Modulate
* j
= (Modulate
*)data
;
22502 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22503 j
->setRandomGain(f
);
22506 UGEN_CGET
Modulate_cget_vibratoRate( t_CKTIME now
, void * data
, void * value
)
22508 Modulate
* j
= (Modulate
*)data
;
22509 SET_NEXT_FLOAT ( value
, j
->vibrato
->m_freq
);
22512 UGEN_CGET
Modulate_cget_vibratoGain( t_CKTIME now
, void * data
, void * value
)
22514 Modulate
* j
= (Modulate
*)data
;
22515 SET_NEXT_FLOAT ( value
, j
->vibratoGain
);
22518 UGEN_CGET
Modulate_cget_randomGain( t_CKTIME now
, void * data
, void * value
)
22520 Modulate
* j
= (Modulate
*)data
;
22521 SET_NEXT_FLOAT ( value
, j
->randomGain
);
22526 UGEN_CTOR
Moog_ctor ( t_CKTIME now
)
22531 UGEN_DTOR
Moog_dtor ( t_CKTIME now
, void * data
)
22533 delete (Moog
*)data
;
22536 UGEN_TICK
Moog_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22538 Moog
* m
= (Moog
*)data
;
22543 UGEN_PMSG
Moog_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22549 UGEN_CTRL
Moog_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22551 Moog
* m
= (Moog
*)data
;
22552 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22557 UGEN_CTRL
Moog_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22559 Moog
* m
= (Moog
*)data
;
22560 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22561 m
->setFrequency ( f
);
22564 UGEN_CTRL
Moog_ctrl_modSpeed( t_CKTIME now
, void * data
, void * value
)
22566 Moog
* m
= (Moog
*)data
;
22567 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22568 m
->setModulationSpeed(f
);
22571 UGEN_CTRL
Moog_ctrl_modDepth( t_CKTIME now
, void * data
, void * value
)
22573 Moog
* m
= (Moog
*)data
;
22574 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22575 m
->setModulationDepth(f
);
22578 UGEN_CTRL
Moog_ctrl_filterQ( t_CKTIME now
, void * data
, void * value
)
22580 Moog
* m
= (Moog
*)data
;
22581 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22582 m
->controlChange( __SK_FilterQ_
, f
* 128.0 );
22585 UGEN_CTRL
Moog_ctrl_filterSweepRate( t_CKTIME now
, void * data
, void * value
)
22587 Moog
* m
= (Moog
*)data
;
22588 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22589 m
->controlChange( __SK_FilterSweepRate_
, f
* 128.0 );
22593 UGEN_CTRL
Moog_ctrl_afterTouch( t_CKTIME now
, void * data
, void * value
)
22595 Moog
* m
= (Moog
*)data
;
22596 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22597 m
->controlChange( __SK_AfterTouch_Cont_
, f
* 128.0 );
22601 UGEN_CGET
Moog_cget_freq( t_CKTIME now
, void * data
, void * value
)
22603 Moog
* m
= (Moog
*)data
;
22604 SET_NEXT_FLOAT ( value
, m
->baseFrequency
);
22607 UGEN_CGET
Moog_cget_modSpeed( t_CKTIME now
, void * data
, void * value
)
22609 Moog
* m
= (Moog
*)data
;
22610 SET_NEXT_FLOAT ( value
, m
->loops
[1]->m_freq
);
22613 UGEN_CGET
Moog_cget_modDepth( t_CKTIME now
, void * data
, void * value
)
22615 Moog
* m
= (Moog
*)data
;
22616 SET_NEXT_FLOAT ( value
, m
->modDepth
* 2.0 );
22619 UGEN_CGET
Moog_cget_filterQ( t_CKTIME now
, void * data
, void * value
)
22621 Moog
* m
= (Moog
*)data
;
22622 SET_NEXT_FLOAT ( value
, 10.0 * ( m
->filterQ
- 0.80 ) );
22625 UGEN_CGET
Moog_cget_filterSweepRate( t_CKTIME now
, void * data
, void * value
)
22627 Moog
* m
= (Moog
*)data
;
22628 SET_NEXT_FLOAT ( value
, m
->filterRate
* 5000 );
22633 UGEN_CTOR
NRev_ctor( t_CKTIME now
)
22635 return new NRev( 4.0f
);
22638 UGEN_DTOR
NRev_dtor( t_CKTIME now
, void * data
)
22640 delete (NRev
*)data
;
22643 UGEN_TICK
NRev_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22645 NRev
* j
= (NRev
*)data
;
22646 *out
= j
->tick( in
);
22650 UGEN_PMSG
NRev_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22655 UGEN_CTRL
NRev_ctrl_mix( t_CKTIME now
, void * data
, void * value
)
22657 NRev
* j
= (NRev
*)data
;
22658 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22659 j
->setEffectMix( f
);
22662 UGEN_CGET
NRev_cget_mix( t_CKTIME now
, void * data
, void * value
)
22664 NRev
* j
= (NRev
*)data
;
22665 SET_NEXT_FLOAT ( value
, j
->effectMix
);
22671 UGEN_CTOR
PitShift_ctor( t_CKTIME now
)
22673 return new PitShift( );
22676 UGEN_DTOR
PitShift_dtor( t_CKTIME now
, void * data
)
22678 delete (PitShift
*)data
;
22681 UGEN_TICK
PitShift_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22683 PitShift
* p
= (PitShift
*)data
;
22684 *out
= p
->tick( in
);
22688 UGEN_PMSG
PitShift_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22693 UGEN_CTRL
PitShift_ctrl_shift( t_CKTIME now
, void * data
, void * value
)
22695 PitShift
* p
= (PitShift
*)data
;
22696 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22700 UGEN_CTRL
PitShift_ctrl_effectMix( t_CKTIME now
, void * data
, void * value
)
22702 PitShift
* p
= (PitShift
*)data
;
22703 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22704 p
->setEffectMix( f
);
22708 UGEN_CGET
PitShift_cget_shift( t_CKTIME now
, void * data
, void * value
)
22710 PitShift
* p
= (PitShift
*)data
;
22711 SET_NEXT_FLOAT (value
, 1.0 - p
->rate
);
22714 UGEN_CGET
PitShift_cget_effectMix( t_CKTIME now
, void * data
, void * value
)
22716 PitShift
* p
= (PitShift
*)data
;
22717 SET_NEXT_FLOAT (value
, p
->effectMix
);
22722 UGEN_CTOR
PRCRev_ctor( t_CKTIME now
)
22724 return new PRCRev( 4.0f
);
22727 UGEN_DTOR
PRCRev_dtor( t_CKTIME now
, void * data
)
22729 delete (PRCRev
*)data
;
22732 UGEN_TICK
PRCRev_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22734 PRCRev
* j
= (PRCRev
*)data
;
22735 *out
= j
->tick( in
);
22739 UGEN_PMSG
PRCRev_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22744 UGEN_CTRL
PRCRev_ctrl_mix( t_CKTIME now
, void * data
, void * value
)
22746 PRCRev
* j
= (PRCRev
*)data
;
22747 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22748 j
->setEffectMix( f
);
22751 UGEN_CGET
PRCRev_cget_mix( t_CKTIME now
, void * data
, void * value
)
22753 PRCRev
* j
= (PRCRev
*)data
;
22754 SET_NEXT_FLOAT ( value
, j
->effectMix
);
22758 UGEN_CTOR
Shakers_ctor( t_CKTIME now
)
22760 return new Shakers
;
22763 UGEN_DTOR
Shakers_dtor( t_CKTIME now
, void * data
)
22765 delete (Shakers
*)data
;
22768 UGEN_TICK
Shakers_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22770 Shakers
* s
= (Shakers
*)data
;
22775 UGEN_PMSG
Shakers_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22780 UGEN_CTRL
Shakers_ctrl_which( t_CKTIME now
, void * data
, void * value
)
22782 Shakers
* s
= (Shakers
*)data
;
22783 t_CKINT c
= GET_CK_INT(value
);
22787 UGEN_CTRL
Shakers_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22789 Shakers
* s
= (Shakers
*)data
;
22790 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22794 UGEN_CTRL
Shakers_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
22796 Shakers
* s
= (Shakers
*)data
;
22797 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22801 UGEN_CTRL
Shakers_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22803 Shakers
* s
= (Shakers
*)data
;
22804 s
->freq
= GET_CK_FLOAT(value
);
22805 s
->controlChange( __SK_ModWheel_
, s
->freq
);
22808 UGEN_CGET
Shakers_cget_which( t_CKTIME now
, void * data
, void * value
)
22810 Shakers
* s
= (Shakers
*)data
;
22811 SET_NEXT_INT( value
, s
->m_noteNum
);
22814 UGEN_CGET
Shakers_cget_freq( t_CKTIME now
, void * data
, void * value
)
22816 Shakers
* s
= (Shakers
*)data
;
22817 SET_NEXT_FLOAT( value
, s
->freq
);
22821 UGEN_CTOR
SubNoise_ctor( t_CKTIME now
)
22823 return new SubNoise( );
22826 UGEN_DTOR
SubNoise_dtor( t_CKTIME now
, void * data
)
22828 delete (SubNoise
*)data
;
22831 UGEN_TICK
SubNoise_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22833 SubNoise
* p
= (SubNoise
*)data
;
22838 UGEN_PMSG
SubNoise_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22840 NRev
* j
= (NRev
*)data
;
22841 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22842 j
->setEffectMix( f
);
22846 UGEN_CTRL
SubNoise_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
22848 SubNoise
* p
= (SubNoise
*)data
;
22849 int i
= GET_CK_INT(value
);
22853 UGEN_CTRL
SubNoise_cget_rate( t_CKTIME now
, void * data
, void * value
)
22855 SET_NEXT_INT( value
, (int)((SubNoise
*)data
)->subRate() );
22861 UGEN_CTOR
VoicForm_ctor( t_CKTIME now
)
22863 return new VoicForm();
22866 UGEN_DTOR
VoicForm_dtor( t_CKTIME now
, void * data
)
22868 delete (VoicForm
*)data
;
22871 UGEN_TICK
VoicForm_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
22873 VoicForm
* m
= (VoicForm
*)data
;
22878 UGEN_PMSG
VoicForm_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
22883 UGEN_CTRL
VoicForm_ctrl_phoneme( t_CKTIME now
, void * data
, void * value
)
22885 VoicForm
* v
= (VoicForm
*)data
;
22886 char *c
= GET_CK_STRING(value
);
22887 v
->setPhoneme( c
);
22890 UGEN_CTRL
VoicForm_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
22892 VoicForm
* v
= (VoicForm
*)data
;
22893 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22894 v
->setFrequency( f
);
22897 UGEN_CTRL
VoicForm_ctrl_noteOn( t_CKTIME now
, void * data
, void * value
)
22899 VoicForm
* v
= (VoicForm
*)data
;
22900 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22904 UGEN_CTRL
VoicForm_ctrl_noteOff( t_CKTIME now
, void * data
, void * value
)
22906 VoicForm
* v
= (VoicForm
*)data
;
22907 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22911 UGEN_CTRL
VoicForm_ctrl_speak( t_CKTIME now
, void * data
, void * value
)
22913 VoicForm
* v
= (VoicForm
*)data
;
22917 UGEN_CTRL
VoicForm_ctrl_quiet( t_CKTIME now
, void * data
, void * value
)
22919 VoicForm
* v
= (VoicForm
*)data
;
22923 UGEN_CTRL
VoicForm_ctrl_voiced( t_CKTIME now
, void * data
, void * value
)
22925 VoicForm
* v
= (VoicForm
*)data
;
22926 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22930 UGEN_CTRL
VoicForm_ctrl_unVoiced( t_CKTIME now
, void * data
, void * value
)
22932 VoicForm
* v
= (VoicForm
*)data
;
22933 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22934 v
->setUnVoiced( f
); //not sure if this should be multiplied
22937 UGEN_CTRL
VoicForm_ctrl_voiceMix( t_CKTIME now
, void * data
, void * value
)
22939 VoicForm
* v
= (VoicForm
*)data
;
22940 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22941 v
->controlChange(__SK_Breath_
, f
* 128.0 );
22944 UGEN_CTRL
VoicForm_ctrl_selPhoneme( t_CKTIME now
, void * data
, void * value
)
22946 VoicForm
* v
= (VoicForm
*)data
;
22947 int i
= GET_CK_INT(value
);
22948 v
->controlChange(__SK_FootControl_
, i
);
22951 UGEN_CTRL
VoicForm_ctrl_vibratoFreq( t_CKTIME now
, void * data
, void * value
)
22953 VoicForm
* v
= (VoicForm
*)data
;
22954 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22955 v
->controlChange( __SK_ModFrequency_
, f
* 128.0 );
22958 UGEN_CTRL
VoicForm_ctrl_vibratoGain( t_CKTIME now
, void * data
, void * value
)
22960 VoicForm
* v
= (VoicForm
*)data
;
22961 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22962 v
->controlChange(__SK_ModWheel_
, f
* 128.0 );
22965 UGEN_CTRL
VoicForm_ctrl_loudness( t_CKTIME now
, void * data
, void * value
)
22967 VoicForm
* v
= (VoicForm
*)data
;
22968 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22969 v
->controlChange(__SK_AfterTouch_Cont_
, f
* 128.0 );
22972 UGEN_CTRL
VoicForm_ctrl_pitchSweepRate( t_CKTIME now
, void * data
, void * value
)
22974 VoicForm
* v
= (VoicForm
*)data
;
22975 t_CKFLOAT f
= GET_CK_FLOAT(value
);
22976 v
->setPitchSweepRate( f
);
22980 UGEN_CGET
VoicForm_cget_phoneme( t_CKTIME now
, void * data
, void * value
)
22982 VoicForm
* v
= (VoicForm
*)data
;
22983 SET_NEXT_STRING ( value
, (char*)Phonemes::name(v
->m_phonemeNum
)); //cast away const!
22986 UGEN_CGET
VoicForm_cget_freq( t_CKTIME now
, void * data
, void * value
)
22988 VoicForm
* v
= (VoicForm
*)data
;
22989 SET_NEXT_FLOAT( value
, v
->voiced
->m_freq
);
22992 UGEN_CGET
VoicForm_cget_voiced( t_CKTIME now
, void * data
, void * value
)
22994 VoicForm
* v
= (VoicForm
*)data
;
22996 SET_NEXT_FLOAT( value
, v
->voiced
->envelope
->value
);
22999 UGEN_CGET
VoicForm_cget_unVoiced( t_CKTIME now
, void * data
, void * value
)
23001 VoicForm
* v
= (VoicForm
*)data
;
23002 SET_NEXT_FLOAT( value
, v
->noiseEnv
->value
);
23005 UGEN_CGET
VoicForm_cget_voiceMix( t_CKTIME now
, void * data
, void * value
)
23007 VoicForm
* v
= (VoicForm
*)data
;
23008 SET_NEXT_FLOAT( value
, v
->voiced
->envelope
->value
);
23011 UGEN_CGET
VoicForm_cget_selPhoneme( t_CKTIME now
, void * data
, void * value
)
23013 VoicForm
* v
= (VoicForm
*)data
;
23014 SET_NEXT_FLOAT ( value
, v
->m_phonemeNum
);
23017 UGEN_CGET
VoicForm_cget_vibratoFreq( t_CKTIME now
, void * data
, void * value
)
23019 VoicForm
* v
= (VoicForm
*)data
;
23020 SET_NEXT_FLOAT ( value
, v
->voiced
->modulator
->vibrato
->m_freq
);
23023 UGEN_CGET
VoicForm_cget_vibratoGain( t_CKTIME now
, void * data
, void * value
)
23025 VoicForm
* v
= (VoicForm
*)data
;
23026 SET_NEXT_FLOAT ( value
, v
->voiced
->modulator
->vibratoGain
);
23029 UGEN_CGET
VoicForm_cget_loudness( t_CKTIME now
, void * data
, void * value
)
23031 VoicForm
* v
= (VoicForm
*)data
;
23032 SET_NEXT_FLOAT( value
, v
->voiced
->envelope
->value
);
23035 UGEN_CGET
VoicForm_cget_pitchSweepRate( t_CKTIME now
, void * data
, void * value
)
23037 VoicForm
* v
= (VoicForm
*)data
;
23038 SET_NEXT_FLOAT( value
, v
->voiced
->m_freq
);
23043 UGEN_CTOR
WvIn_ctor( t_CKTIME now
)
23048 UGEN_DTOR
WvIn_dtor( t_CKTIME now
, void * data
)
23050 delete (WvIn
*)data
;
23053 UGEN_TICK
WvIn_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
23055 WvIn
* w
= (WvIn
*)data
;
23056 *out
= ( w
->m_loaded
? (t_CKFLOAT
)w
->tick() / SHRT_MAX
: (SAMPLE
)0.0 );
23060 UGEN_PMSG
WvIn_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
23062 VoicForm
* v
= (VoicForm
*)data
;
23063 t_CKFLOAT f
= GET_CK_FLOAT(value
);
23064 v
->controlChange(__SK_ModWheel_
, f
* 128.0 );
23068 UGEN_CTRL
WvIn_ctrl_rate( t_CKTIME now
, void * data
, void * value
)
23070 WvIn
* w
= (WvIn
*)data
;
23071 t_CKFLOAT f
= GET_CK_FLOAT(value
);
23075 UGEN_CTRL
WvIn_ctrl_path( t_CKTIME now
, void * data
, void * value
)
23077 WvIn
* w
= (WvIn
*)data
;
23078 char * c
= *(char **)value
;
23079 try { w
->openFile( c
, FALSE
, FALSE
); }
23080 catch( StkError
& e
)
23083 const char * s
= e
.getMessage();
23084 // fprintf( stderr, "[chuck](via STK): WvIn cannot load file '%s'\n", c );
23089 UGEN_CGET
WvIn_cget_rate( t_CKTIME now
, void * data
, void * value
)
23091 WvIn
* w
= (WvIn
*)data
;
23092 SET_NEXT_FLOAT ( value
, w
->rate
);
23095 UGEN_CGET
WvIn_cget_path( t_CKTIME now
, void * data
, void * value
)
23097 WvIn
* w
= (WvIn
*)data
;
23098 SET_NEXT_STRING ( value
, w
->m_filename
);
23102 UGEN_CTOR
WaveLoop_ctor( t_CKTIME now
)
23104 return new WaveLoop
;
23107 UGEN_DTOR
WaveLoop_dtor( t_CKTIME now
, void * data
)
23109 delete (WaveLoop
*)data
;
23112 UGEN_TICK
WaveLoop_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
23114 WaveLoop
* w
= (WaveLoop
*)data
;
23115 *out
= ( w
->m_loaded
? (t_CKFLOAT
)w
->tick() / SHRT_MAX
: (SAMPLE
)0.0 );
23119 UGEN_PMSG
WaveLoop_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
23124 UGEN_CTRL
WaveLoop_ctrl_freq( t_CKTIME now
, void * data
, void * value
)
23126 WaveLoop
* w
= (WaveLoop
*)data
;
23127 t_CKFLOAT f
= GET_CK_FLOAT(value
);
23128 w
->setFrequency( f
);
23131 UGEN_CTRL
WaveLoop_ctrl_phase( t_CKTIME now
, void * data
, void * value
)
23133 WaveLoop
* w
= (WaveLoop
*)data
;
23134 float f
= (float)GET_CK_FLOAT(value
);
23138 UGEN_CTRL
WaveLoop_ctrl_phaseOffset( t_CKTIME now
, void * data
, void * value
)
23140 WaveLoop
* w
= (WaveLoop
*)data
;
23141 t_CKFLOAT f
= GET_CK_FLOAT(value
);
23142 w
->addPhaseOffset( f
);
23147 UGEN_CGET
WaveLoop_cget_freq( t_CKTIME now
, void * data
, void * value
)
23149 WaveLoop
* w
= (WaveLoop
*)data
;
23150 SET_NEXT_FLOAT ( value
, w
->m_freq
);
23153 UGEN_CGET
WaveLoop_cget_phase( t_CKTIME now
, void * data
, void * value
)
23155 WaveLoop
* w
= (WaveLoop
*)data
;
23156 SET_NEXT_FLOAT ( value
, w
->time
/ w
->fileSize
);
23159 UGEN_CGET
WaveLoop_cget_phaseOffset( t_CKTIME now
, void * data
, void * value
)
23161 WaveLoop
* w
= (WaveLoop
*)data
;
23162 SET_NEXT_FLOAT ( value
, w
->phaseOffset
);
23165 std::map
<WvOut
*, WvOut
*> g_wv
;
23168 UGEN_CTOR
WvOut_ctor( t_CKTIME now
)
23170 WvOut
* yo
= new WvOut
;
23171 strcpy( yo
->autoPrefix
, "chuck-session" );
23175 UGEN_DTOR
WvOut_dtor( t_CKTIME now
, void * data
)
23177 WvOut
* w
= (WvOut
*)data
;
23179 std::map
<WvOut
*, WvOut
*>::iterator iter
;
23180 iter
= g_wv
.find( w
);
23181 g_wv
.erase( iter
, iter
);
23182 delete (WvOut
*)data
;
23185 UGEN_TICK
WvOut_tick( t_CKTIME now
, void * data
, SAMPLE in
, SAMPLE
* out
)
23187 WvOut
* w
= (WvOut
*)data
;
23188 if( w
->start
) w
->tick( in
);
23189 *out
= in
; // pass samples downstream
23193 UGEN_PMSG
WvOut_pmsg( t_CKTIME now
, void * data
, const char * msg
, void * value
)
23198 // XXX chuck got mono, so we have one channel. fix later.
23199 UGEN_CTRL
WvOut_ctrl_matFilename( t_CKTIME now
, void * data
, void * value
)
23201 WvOut
* w
= (WvOut
*)data
;
23202 char *filename
= * (char**) value
;
23206 if( strstr( filename
, "special:auto" ) )
23208 time_t t
; time(&t
);
23209 strcpy( buffer
, w
->autoPrefix
);
23210 strcat( buffer
, "(" );
23211 strncat( buffer
, ctime(&t
), 24 );
23212 buffer
[strlen(w
->autoPrefix
)+14] = 'h';
23213 buffer
[strlen(w
->autoPrefix
)+17] = 'm';
23214 strcat( buffer
, ").mat" );
23217 w
->openFile( filename
, 1, WvOut::WVOUT_MAT
, Stk::STK_SINT16
);
23221 UGEN_CTRL
WvOut_ctrl_sndFilename( t_CKTIME now
, void * data
, void * value
)
23223 WvOut
* w
= (WvOut
*)data
;
23224 char *filename
= * (char**) value
;
23228 if( strstr( filename
, "special:auto" ) )
23230 time_t t
; time(&t
);
23231 strcpy( buffer
, w
->autoPrefix
);
23232 strcat( buffer
, "(" );
23233 strncat( buffer
, ctime(&t
), 24 );
23234 buffer
[strlen(w
->autoPrefix
)+14] = 'h';
23235 buffer
[strlen(w
->autoPrefix
)+17] = 'm';
23236 strcat( buffer
, ").snd" );
23239 w
->openFile( filename
, 1, WvOut::WVOUT_SND
, Stk::STK_SINT16
);
23243 UGEN_CTRL
WvOut_ctrl_wavFilename( t_CKTIME now
, void * data
, void * value
)
23245 WvOut
* w
= (WvOut
*)data
;
23246 char *filename
= * (char**) value
;
23250 if( strstr( filename
, "special:auto" ) )
23252 time_t t
; time(&t
);
23253 strcpy( buffer
, w
->autoPrefix
);
23254 strcat( buffer
, "(" );
23255 strncat( buffer
, ctime(&t
), 24 );
23256 buffer
[strlen(w
->autoPrefix
)+14] = 'h';
23257 buffer
[strlen(w
->autoPrefix
)+17] = 'm';
23258 strcat( buffer
, ").wav" );
23261 w
->openFile( filename
, 1, WvOut::WVOUT_WAV
, Stk::STK_SINT16
);
23265 UGEN_CTRL
WvOut_ctrl_rawFilename( t_CKTIME now
, void * data
, void * value
)
23267 WvOut
* w
= (WvOut
*)data
;
23268 char *filename
= * (char**) value
;
23272 if( strstr( filename
, "special:auto" ) )
23274 time_t t
; time(&t
);
23275 strcpy( buffer
, w
->autoPrefix
);
23276 strcat( buffer
, "(" );
23277 strncat( buffer
, ctime(&t
), 24 );
23278 buffer
[strlen(w
->autoPrefix
)+14] = 'h';
23279 buffer
[strlen(w
->autoPrefix
)+17] = 'm';
23280 strcat( buffer
, ").raw" );
23283 w
->openFile( filename
, 1, WvOut::WVOUT_RAW
, Stk::STK_SINT16
);
23287 UGEN_CTRL
WvOut_ctrl_aifFilename( t_CKTIME now
, void * data
, void * value
)
23289 WvOut
* w
= (WvOut
*)data
;
23290 char *filename
= * (char**) value
;
23294 if( strstr( filename
, "special:auto" ) )
23296 time_t t
; time(&t
);
23297 strcpy( buffer
, w
->autoPrefix
);
23298 strcat( buffer
, "(" );
23299 strncat( buffer
, ctime(&t
), 24 );
23300 buffer
[strlen(w
->autoPrefix
)+14] = 'h';
23301 buffer
[strlen(w
->autoPrefix
)+17] = 'm';
23302 strcat( buffer
, ").aiff" );
23305 w
->openFile( filename
, 1, WvOut::WVOUT_AIF
, Stk::STK_SINT16
);
23309 UGEN_CTRL
WvOut_ctrl_closeFile( t_CKTIME now
, void * data
, void * value
)
23311 WvOut
* w
= (WvOut
*)data
;
23314 std::map
<WvOut
*, WvOut
*>::iterator iter
;
23315 iter
= g_wv
.find( w
);
23316 g_wv
.erase( iter
, iter
);
23319 UGEN_CTRL
WvOut_ctrl_record( t_CKTIME now
, void * data
, void * value
)
23321 WvOut
* w
= (WvOut
*)data
;
23322 t_CKINT i
= GET_NEXT_INT(value
);
23323 w
->start
= i
? 1 : 0;
23326 UGEN_CTRL
WvOut_ctrl_autoPrefix( t_CKTIME now
, void * data
, void * value
)
23328 WvOut
* w
= (WvOut
*)data
;
23329 strcpy( w
->autoPrefix
, GET_NEXT_STRING(value
) );
23332 UGEN_CGET
WvOut_cget_filename( t_CKTIME now
, void * data
, void * value
)
23334 WvOut
* w
= (WvOut
*)data
;
23335 SET_NEXT_STRING( value
, w
->m_filename
);
23338 UGEN_CGET
WvOut_cget_record( t_CKTIME now
, void * data
, void * value
)
23340 WvOut
* w
= (WvOut
*)data
;
23341 SET_NEXT_INT( value
, w
->start
);
23344 UGEN_CGET
WvOut_cget_autoPrefix( t_CKTIME now
, void * data
, void * value
)
23346 WvOut
* w
= (WvOut
*)data
;
23347 SET_NEXT_STRING( value
, w
->autoPrefix
);
23350 //-----------------------------------------------------------------------------
23351 // name: ck_detach()
23353 //-----------------------------------------------------------------------------
23354 t_CKBOOL
stk_detach( t_CKUINT type
, void * data
)
23356 std::map
<WvOut
*, WvOut
*>::iterator iter
;
23358 for( iter
= g_wv
.begin(); iter
!= g_wv
.end(); iter
++ )
23360 (*iter
).second
->closeFile();