RTcmix Quick Reference
Just the basics. Much more detail at rtcmix.org.
Note: function arguments in [ ] are optional.
For more, consult the documentation for the Minc parser.
for (init; test; increment) { // block of statements }
e.g.,
for (start = 0; start < total_duration; start = start + time_increment) { // do something interesting }
or ...
while (test) { // block of statements }e.g.,
start = 0 while (start < total_duration) { // do something interesting start = start + time_increment }
The for
and while
examples above are identical in
effect. Use whichever makes the most sense to you. But if you use a
while
loop, remember to add the line that increments the
variable you test on the while
line, or else you’ll
have an infinite loop!
if (x > 0) { // or <, >=, <=, ==, != // do something fun } else if { // do something exciting } else { // do something boring }
You don’t need the “else” statements, but if you have several of them, the last one must be an “else,” not an “else if.”
mylist = { item0, item1, item2, ..., itemN-1 } numitems = len(mylist)
Items can be any combination of numbers, strings (in double quotes), other lists, or table references (like envelopes).
Write to a list element like this...
mylist[0] = 99.9Read a list element like this...
myval = mylist[4]
Note that lists are zero-based — that is, the index of the first element is 0; the second, 1; the last, N-1, where N is the number of items in the list. If you try to read with an index >= N, Minc returns the last item of the list. If you try to write to an index >= N, Minc expands the size of the list to accommodate the new data.
A common contraction...
start += incrementis the same as...
start = start + increment
Same for the -, *, and / operators. Be sure not to add any space between the + (or other operator) and the =.
Define your own functions. You must put them above the place in the score where you use them.
Here is an example of defining a function and then using it.
float play_triad(float start, float root) { pan = 0.5 WAVETABLE(start, dur, amp * env, root, pan) WAVETABLE(start, dur, amp * env, root + 0.03, pan) WAVETABLE(start, dur, amp * env, root + 0.07, pan) return start + dur // end time of chord } dur = 1 amp = 4000 env = maketable("line", 1000, 0,0, 1,1, 2,0) end = play_triad(0, 8.00) end = play_triad(end, 8.05) end = play_triad(end, 8.01) play_triad(end, 7.09)
Notice that pan
is a local variable that exists only
within the function. If you were to try using it outside of the function,
you would probably get an error. To avoid confusion between global and
local variables, you can use an underscore as the first character of all
local variable names, e.g., _pan
, or use a ‘g’ in
front of all global variables, e.g., gDur
. (This is purely for
the reader’s benefit — it does not affect RTcmix behavior.)
Notice that we use the returned end time as the start time for the next chord, and that you can ignore the return value, as in the last chord.
Functions can have zero or more arguments. Data types include float, string, list, and handle (which is what a table is, for example). For more about user functions, search for “custom functions” on the Minc documentation page.
You can include a score inside another one by using an include statement.
include myfunctions.sco
Then everything in the included file will be treated as if you had typed it into the main file. So if a global variable is declared in the included file, it will be global inside the main file as well.
Include files are especially handy for building a library of functions that you use in many scores. When doing this, it makes sense to use underscores as the first character of global variables within the library, so that you’ll be less likely to access them unintentionally in the file that uses the library.
NOTE: These four are for use only in cmd-line RTcmix, not in any RTcmix apps, such as RTcmixShell.
rtsetparams(sample_rate, num_channels) set_option("play = off") // don't play while I'm writing a sound file set_option("clobber = on") // overwrite existing output file load("INSTRUMENT_NAME")
rtinput("soundfile_name") // must include extension, e.g., ".wav", ".aiff" duration = DUR() // of most recently opened input file rtoutput("soundfile_name.wav") // or ".aiff"
NOTE: rtoutput
works only in
cmd-line RTcmix.
val = irand(min, max) // returns floating-point value val = trand(min, max) // val is truncated (i.e., integer) val = random() // val is between 0 and 1 val = rand() // val is between -1 and 1 srand(seed) // seed is any integer
freq_in_Hz = cpspch(pitch_in_octave_point_pc) pitch_in_octave_point_pc = pchcps(freq_in_Hz) freq_in_Hz = cpsmidi(midi_notenum) pitch_in_octave_point_pc = pchmidi(midi_notenum) pitch = pchadd(pitch1, pitch2) // all in oct.pc
pchadd
prevents you from getting an inappropriate result
when computing pitches using oct.pc. For example, if you were to
subtract one semitone (0.01) from middle C (8.00), you would get
7.99, which is about 8 octaves higher than what you intended. No
other pitch representations have this problem, so you can use
arithmetic operators freely with them.
linear_amp = ampdb(dB) dB = dbamp(linear_amp)
table = maketable(type, [norm,] size, description)
where type can be: "line", "curve", "wave", "random", "literal", "textfile", etc. (complete list here). The type must be in double quotes.
norm is either "norm" (the default) or "nonorm". This is optional. "nonorm" prevents the table from being scaled to the 0-1 range (or -1 to 1, if it contains any negative numbers). These tags must be in double quotes.
size is number of elements in table
remaining arguments depend on type:
stream = makeLFO(wavetable, frequency, amp)
where wavetable can be a previously defined table or a double-quoted name such as you would pass to maketable("wave"...), frequency is LFO rate in Hz, and amp is the peak deviation. (For example, if amp is 2, the waveform will oscillate between -2 and 2.) Instead of amp, you can give min and max arguments defining the amplitude extremes of the wave. All parameters except for wavetable can be constants or references to tables or other streams.
stream = makerandom(type, frequency, min, max[, seed])
where type is one of the random distributions listed for maketable("random"...) above, frequency is how fast the random value changes, min and max define the range of values, and seed is an optional integer seed. The frequency, min, and max parameters can be constants or references to tables or streams.
NOTE: A stream should not be used in multiple instruments that play simultaneously, or else the streams will run at a frequency different from the one you requested. This applies also to streams processed by makefilter and/or makeconverter (see below).
Values entering an instrument from a table or stream cannot be converted by the pitch and amplitude conversion functions listed earlier. These functions are designed to convert a single value, not a sequence of values read at the control rate. Instead, use makeconverter.
// gliss down a perfect 5th from middle C, using MIDI note numbers mpitch = maketable("line", "nonorm", 1000, 0,60, 1,53) freq = makeconverter(mpitch, "cpsmidi")
Think of makeconverter as processing the data stream stored in
the mpitch
variable.
All the conversion function names listed earlier can be used with makeconverter.
Sometimes values from a table or stream change too abruptly (e.g., when using "square" as an LFO waveform). Smooth these changes with a data filter.
freq = makerandom("even", rfreq=6, min=200, max=800) freq = makefilter(freq, "smooth", lag=50, initval=500)
Notice that it’s okay to use the same variable name (freq
in this case) for the input and output of makefilter (or of
makeconverter).
There are other data filter types: clip, constrain, delay, fitrange, invert, map, and quantize. See the online documentation for details.
bus_config("INSTRUMENT_NAME", [input_bus,] output_bus)
where input_bus can be "in 0-1", "aux 0 in", or "aux 0-1 in", and output_bus can be "out 0", "out 0-1", "aux 0 out", or "aux 0-1 out". There are 64 internal (aux) buses. The number of input and output buses depends on your audio hardware. For file input, the "in 0-1" tag does not let you select input channels. Instead, most processing instruments have an inchan argument that lets you do that. Obviously, only instruments that process audio can have an input bus.
Instruments reading from an aux bus must have an inskip of zero. Certain instruments, like TRANS or REVMIX, cannot consume real-time input, because they might need to use audio that hasn't happened yet.
control_rate(rate_in_Hz)
This is just a selection of instruments. For more, go here.
Note: pan always works like this: hard left = 1, center = 0.5, hard right = 0. (Yes, this looks backwards.)
// chaotic noise generator CRACKLE(start, duration, peak_amp[, chaos_param, pan]) // chaos_param is 0-1, default=1 // simple 2-operator Chowning FM FMINST(start, duration, peak_amp, carrier_freq, modulator_freq, min_modindex, max_modindex, pan, wavetable, index_guide_table) // physical model of metallophones MBANDEDWG(start, duration, peak_amp, freq, strike_position, pluck_flag, max_velocity, preset, bow_pressure, mode_resonance, integration_constant, pan) // strike_position [0-1] // pluck_flag [0: no pluck, 1: pluck] // max_velocity [0-1] // preset [0: uniform bar, 1: tuned bar, 2: glass harmonica, 3: Tibetan bowl] // bow_pressure [0-1, 0 mean strike only] // mode_resonance [0-1, 0.99 for normal strike] // integration_constant [0-1, try 0] // white noise NOISE(start, duration, peak_amp, pan) // affected by srand() // Karplus-Strong plucked string model STRUM2(start, duration, peak_amp, freq, squish, decay_time, pan) // vector synthesis using any number of wavetables VWAVE(start, duration, freq, peak_amp, pan, vector_guide, wavetab1, wavetab2, ..., wavetabN) // vector_guide is 0-1, controlling wavetable selection // and cross-fading // simple wavetable synthesis WAVETABLE(start, duration, peak_amp, freq, pan[, wavetable]) // combine two wavetable oscillators algebraically WAVY(start, duration, peak_amp, oscilA_freq, oscilB_freq, oscilB_phase_offset, oscilA_wavetable, oscilB_wavetable, expression, pan) // expression can be "a + b", "a - b", "a * b", etc.
// recursive comb filter COMBIT(start, inskip, duration, amp_multiplier, freq, reverb_time, inchan, pan, ringdown_duration) // delay line with feedback DELAY(start, inskip, duration, amp_multiplier, delay_time, feedback, ringdown_duration, inchan, pan) // distortion DISTORT(start, inskip, duration, amp_multiplier, type=1, pre_gain, lowpass_cf, inchan, pan, bypass) // any number of band-pass filters, fed in parallel FILTERBANK(start, inskip, duration, amp_multiplier, ringdown_duration, inchan, pan, cf1, bw1, gain1, cf2, bw2, gain2, ..., cfN, bwN, gainN) // bw is bandwidth as percent of cf, from 0 to 1 // reverberation FREEVERB(start, inskip, input_duration, amp_multiplier, room_size, pre_delay_time, ringdown_duration, damp, dry_level, wet_level, stereo_width) // last 4 args are 0-100, room_size is 0-1.07143 (don't ask) // any number of EQ filters, fed in series MULTEQ(start, inskip, duration, amp_multiplier, master_bypass, type1, freq1, q1, gain1, bypass1, ..., type2, freq2, q2, gain2, bypass2, ..., typeN, freqN, qN, gainN, bypassN) // type is "lowpass", "highpass", "lowshelf", "highshelf", // "peaknotch", "bandpass" // play a sound file backwards from the inskip REVMIX(start, inskip, duration, amp_multiplier, inchan, pan) // waveshaping SHAPE(start, inskip, duration, amp_multiplier, min_distort_index, max_distort_index, amp_norm_table, inchan, pan, transfer_function_table, index_guide_table) // play a sound file forwards STEREO(start, inskip, duration, amp_multiplier, pan) // play a sound file forwards, with varispeed transposition // (i.e., transposition affects duration) TRANS(start, inskip, duration, amp_multiplier, transp_in_octave_point_pc, inchan, pan)