You can open the settings menu panel using the gear button in the top-right corner of the screen.
Volume: Global audio volume
BPM: Beats-per-minute (BPM) for sequencers
Resolution: Graphics resolution (low, mid, high, ultra)
Post Processing: Enable/disable post processing
Load: Load a project
Save: Save a project
Rescan: Rescan MIDI devices + ChucK source directory
Source Directory: Open the source directory in file browser. You can use this to locate template scripts for Voice unit and VFX unit.
Dual Display: Display a full-screen view of the canvas if there is a second monitor available.
Left-click: Select and move a unit
Ctrl/Cmd/Shift + left-click: Select and move multiple units | Use selection box tool
Right-click + drag: Shift camera
Scroll wheel: Zoom in/out
~: Open / close console
Space: Re-sync sequencer steps
Delete: Destroy selected units
Escape: Deselect selected units / Exit performance mode
N: Spawn a number box
E: Enter edit mode of selected unit (if applicable)
M: Open submenu of the unit in edit mode (if applicable)
Arrow keys: Shift camera
+/-: Zoom in/out
C: Control Selection Panel
V: Voice Selection Panel
G: Graphics Selection Panel
Ctrl/Cmd + A: Select all units
Ctrl/Cmd + C: Copy selected units
Ctrl/Cmd + X: Cut selected units
Ctrl/Cmd + V: Paste copied units
Ctrl/Cmd + Z: Undo
Ctrl/Cmd + Y: Redo
Ctrl/Cmd + S: Save a project
Ctrl/Cmd + P: Load a project
Ctrl/Cmd + T: Toggle "performance" mode
Ctrl/Cmd + R: Randomize all steps in sequencer edit mode
Below is a list of available units in RayTone by category. In this documentation, the following symbols are used to represent the unit socket types.
➡️: control-rate inlet
↩️: control-rate outlet
➡️🔊: audio-rate input
↩️🔊: audio-rate output
Additionally, the following symbol is used if a unit has a submenu panel for editing additional properties. You can either double click on the unit or click on the edit key on the right side of the screen to enter the edit mode.
🎚️: unit submenu panel
A GUI unit for monitoring a number every frame.
➡️: value to monitor
A GUI unit for setting a constant number. Click on the box to edit the value.
↩️: value
A circular step sequencer that outputs a value every step. Double click or click on the edit key on the right side of the screen to enter the edit mode. Use left and right arrow keys to select a step to edit. Use up and down arrow keys to edit the step value.
Ctrl/Cmd + up or down key to move all steps.
Shift + up or down key to move in increments of 10.
Ctrl/Cmd + R to randomize all steps within the range specified in submenu.
↩️: step value
🎚️: submenu panel
Step: number of steps. Change this to experiment with polymeters.
Clock: clock division to control the sequencer tempo. Change this to experiment with polyrhythms. By default, the slider changes the clock division by powers of 2. Alternatively, click on the number to manually specify the value.
min: minimum step value
max: maximum step value
delta: step value increment
A GUI slider.
↩️: value between 0 and 1
A GUI toggle button.
↩️: 0 or 1 (lit).
A GUI button. Use this to manually send a trigger.
↩️: trigger on click
➡️: value
↩️: absolute value of inlet1
➡️: value1
➡️: value2
↩️: inlet1 + inlet2
➡️: value
↩️: nearest integer equal to or higher than value of inlet1
➡️: value
➡️: min
➡️: max
↩️: clamped value
➡️: radian angle
↩️: cos(inlet1)
➡️: numerator
➡️: denominator
↩️: inlet1 / inlet2. 0 if inlet2 = 0.
➡️: value1
➡️: value2
↩️: 1 if value1=value2. 0 if not.
➡️: value
↩️: nearest integer equal to or lower than value of inlet1
➡️: frequency value
↩️: inlet1 converted to midi note number
➡️: value1
➡️: value2
↩️: 1 if value1 > value2. 0 if not.
➡️: from
➡️: to
➡️: weight
↩️: clamped linear interpolation between From and To values using weight (0-1).
➡️: value
➡️: log base
↩️: loginlet2(inlet1)
➡️: value1
➡️: value2
↩️: maximum value between inlet1 and inlet2
➡️: value1
➡️: value2
↩️: minimum value between inlet1 and inlet2
➡️: midi note number
↩️: inlet1 converted to frequency
➡️: value1
➡️: value2
↩️: inlet1 * inlet2
↩️: π ≈ 3.14159...
➡️: value
➡️: exponent
↩️: inlet1 raised to the power of inlet2
➡️: value
↩️: inlet1 rounded to the nearest integer
➡️: radian angle
↩️: sin(inlet1)
➡️: value
↩️: square root of inlet1
➡️: value1
➡️: value2
↩️: value1 - value2
Take the exponential moving average of the inlet value. Use this unit to smoothly interpolate between discrete values.
➡️: value
➡️: average time (ms): default is 500ms
↩️: inlet1 averaged over inlet2.
Set and get current global BPM. Use this unit in a project to explicitly set its BPM when loaded.
➡️: new BPM
↩️: current BPM
↩️: current day of the month
Return the elapsed time in seconds since RayTone application started OR the last reset time. Use this unit to obtain a value that linearly increases over time.
➡️: reset (trigger)
↩️: elapsed time
↩️: current hour in 24-hour format
↩️: current millisecond
↩️: current minute
↩️: current month
↩️: current second
↩️: current year
A counter that increments a value on BPM-dependent trigger.
➡️: increment +1 (trigger)
➡️: reset (trigger)
↩️: current value
Monitor a computer key press either continuously or as one-shot. This unit is useful for updating canvas parameters (Voice, VFX, etc.) in live performance and debugging settings.
↩️: key status (0 or 1).
🎚️: submenu panel
Key: computer key to monitor; default is 'A'
Continuous: whether to treat a key press as held/released (lit) or as a single click (unlit).
Receive MIDI CC value at specified channel and CC number. Use this unit to communicate with audio and graphics hardware.
↩️: Incoming MIDI CC value.
🎚️: submenu panel
MIDI channel: default is 1
CC Number: default is 60
Send MIDI CC value at specified channel and CC number. Use this unit to communicate with audio and graphics hardware.
➡️: CC value to send
🎚️: submenu panel
MIDI Channel: default is 1
CC Number: default is 60
Receive OSC floating point value at specified port and OSC address. Use this unit to communicate with other audio and graphics software.
↩️: OSC value.
🎚️: submenu panel
port: default is 5001
OSC address: default is /raytone/osc-r
Send OSC floating point value at specified IP address, port and OSC address. Use this unit to communicate with other audio and graphics software.
➡️: value to send via OSC every frame.
🎚️: submenu panel
IP address: default is localhost 127.0.0.1
port: default is 5000
OSC address: default is /raytone/osc-s
➡️: trigger
↩️: random value between 0 and 1 on trigger
A "switch" unit that returns the value at the specified "key" index (starting with 0). This unit is useful for creating scene states, such as which sequencer and texture are actively used.
➡️: 0
➡️: 1
➡️: 2
➡️: 3
➡️: 4
➡️: 5
➡️: 6
➡️: 7
➡️: key
↩️: value at the key index
↩️: trigger every step. This is equivalent to a sequencer with all steps at 1 with clock division=1.
Set and get current global volume. Use this unit in a project to explicitly set its volume when loaded.
➡️: new volume
↩️: current volume
🎚️: every voice unit has a submenu panel
volume: local volume to DAC. Note that this value is not effective if the unit is connected to another voice unit since only the second unit would have audio output to DAC.
spatialize: turn on/off panning. When turned on, the placement of the voice unit relative to the camera pans the output signal. Turn this off for sounds that you don't want to pan.
➡️: freq
➡️: bow pressure
➡️: bow position
➡️: vibrato frequency
➡️: vibrato depth
↩️🔊: A digital waveguide bowed string model. https://chuck.stanford.edu/doc/reference/ugens-stk.html#Bowed
Same as Bow, except that all inlets are read once a step. Use this version for accurate timing unbounded by frame-rate.
➡️: carrier frequency
➡️: modulator frequency ratio to inlet1
➡️: FM index of modulation
↩️🔊: 2-operator frequency modulation synthesis.
Same as FM, except that all inlets are read once a step. Use this version for accurate timing unbounded by frame-rate.
↩️🔊: white nosie
➡️: frequency
↩️🔊: sinusoidal oscillator
Same as OSC, except that all inlets are read once a step. Use this version for accurate timing unbounded by frame-rate.
➡️: frequency
➡️: duty cycle width
↩️🔊: pulse width oscillator
Same as Pulse, except that all inlets are read once a step. Use this version for accurate timing unbounded by frame-rate.
➡️: trigger
➡️: rate (1 if cable not connected)
↩️🔊: .wav sample playback sampler
➡️: freq
➡️: whether sawtooth wave is to fall (0) or rise (1)
↩️🔊: sawtooth oscillator
Same as Saw, except that all inlets are read once a step. Use this version for accurate timing unbounded by frame-rate.
➡️: frequency
↩️🔊: square wave oscillator
Same as Square, except that all inlets are read once a step. Use this version for accurate timing unbounded by frame-rate.
➡️: frequency
➡️: width of triangle wave (ratio of rise time to fall time)
↩️🔊: triangle wave oscillator
Same as Tri, except that all inlets are read once a step. Use this version for accurate timing unbounded by frame-rate.
➡️🔊: signal in
➡️: cutoff frequency
➡️: filter Q
↩️🔊: input signal => bandpass filter
➡️🔊: signal in
➡️: chorus frequency
➡️: chorus depth
↩️🔊: input signal => chorus
➡️🔊: signal in
➡️: delay time (ms)
➡️: feedback (0-1)
↩️🔊: input signal => feedback delay
➡️🔊: signal in
➡️: cutoff frequency
↩️🔊: input signal => highpass filter
➡️🔊: signal in
➡️: cutoff frequency
↩️🔊: input signal => lowpass filter
➡️🔊: signal in
➡️: degree of pitch shifting
↩️🔊: input signal => pitchshifter
➡️🔊: signal in
➡️: dry/off (0-1). 0.03 if cable is not connected.
↩️🔊: input signal => beloved John Chowning reverb
➡️🔊: signal1 in
➡️🔊: signal2 in
➡️🔊: signal3 in
➡️🔊: signal4 in
↩️🔊: input1 + input2 + input3 + input4
➡️🔊: signal in
➡️: trigger (open envelope)
➡️: attack (ms)
➡️: release (ms)
↩️🔊: input signal => AR enveloped VCA. Use this unit to shape the envelope of a signal with attack and release stages.
➡️🔊: signal in
➡️: gain multiplier. 0 if cable not connected.
↩️🔊: input signal => gain
➡️🔊: signal1 in
➡️🔊: signal2 in
↩️🔊: sample-by-sample multiplication of input1 and input2.
Use this unit to analyze the spectral centroid (center of mass of spectrum) of audio signals from another voice unit (or a chained series of voice units).
➡️🔊: signal in
↩️🔊: N/A
↩️: Spectrum centroid of input1.
Use this unit to estimate the fundamental frequency of audio signals from another voice unit (or a chained series of voice units). By combining with other voice units (oscillators), this can be used to resynthesize and harmonize with a sound file.
➡️🔊: signal in
↩️🔊: N/A
↩️: Estimated fundamental frequency of input1.
Use this unit to analyze loudness of audio signals from another voice unit (or a chained series of voice units) and apply the result to control / graphics unit inlets, such as a VFX inlet.
➡️🔊: signal in
↩️🔊: N/A
↩️: RMS analysis of input1.
Signal to Number Converter. Use this unit to convert audio signals from another voice unit (or a chained series of voice units) to a floating point value and apply the result to control / graphics unit inlets, such as a VFX inlet.
➡️🔊: signal in
↩️🔊: N/A
↩️: An audio sample of input1 converted to a floating point value every 1ms.
You can write your custom voice units using Chuck! Open the RayTone source directory from the settings panel (top right corner) and take a look at the template.ck file in ChucK/User folder to get started. New .ck files in this folder will appear as new voice units after clicking on Rescan button from the settings panel . Additionally, you can create new voice unit categories by adding folders parallel to this User folder.
Use the following macros to define voice unit sockets:
RAYTONE_DEFINE_INPUTS("signal1", "signal2"); audio-rate input names with double quotation marks separated by commas.
RAYTONE_DEFINE_INLETS("dry/wet 0-1", "Inlet2Name..."); control-rate inlet names with double quotation marks separated by commas.
RAYTONE_DEFINE_OUTLET(true); set to true to add a control-rate outlet
RAYTONE_LOADFILE(false); set to true open a file browser to load a .wav file to this script. (For example, Sampler voice unit uses this feature.)
In order to send a signal to DAC and the output socket, you must add the following to your signal chain:
(Your Signal Chain) => RAYTONE_OUTPUT => dac;
Inside the ChucK script, you can read input and inlet values using the following macros:
RAYTONE_INPUT(0) Use an index starting at 0 inside the parentheses to access an input defined by RAYTONE_DEFINE_INPUTS().
RAYTONE_INLET(0) Use an index starting at 0 inside the parentheses to access an inlet defined by RAYTONE_DEFINE_INLETS().
You can send a float variable to the control-rate outlet using the following macro only if RAYTONE_DEFINE_OUTLET() is set to true:
RAYTONE_OUTLET
If RAYTONE_LOADFILE() is set to true, you can access the file path that is loaded to a voice unit using the following macro:
RAYTONE_FILEPATH
The tick in RayTone is defined as a ChucK global event:
RAYTONE_TICK
Putting this all together... the following code is an example taken from the Sampler voice unit:
//-----------------------------------------------------------------------------
//Define RayTone inputs & inlets & file requirement
RAYTONE_DEFINE_INPUTS();
RAYTONE_DEFINE_INLETS("trigger", "rate");
RAYTONE_DEFINE_OUTLET(false);
RAYTONE_LOADFILE(true);
//-----------------------------------------------------------------------------
// Create a signal chain using the SndBuf class to play an audio clip
SndBuf buf => RAYTONE_OUTPUT => dac;
// Load a .wav file to SndBuf
RAYTONE_FILEPATH => buf.read;
0 => buf.gain;
// infinite loop
while (true)
{
// Advance time until the global clock
RAYTONE_TICK => now;
// Check if inlet0 received a trigger
If (RAYTONE_TRIG(0) == 1)
{
// Reset SndBuf gain
RAYTONE_LOCAL_GAIN => buf.gain;
// Read playback rate from inlet1.
// If inlet1 is not connected, set playback rate to 1.
if (RAYTONE_INLET_STATUS(1) == 1)
{
RAYTONE_INLET(1) => buf.rate;
}
else
{
1 => buf.rate;
}
// Read playback position in ms from inlet2.
(RAYTONE_INLET(2) / (buf.length() / 1::ms) * buf.samples()) $ int => buf.pos;
}
}
Export the connected texture as .png in the Exports folder of RayTone source directory, which you can access from the global settings panel.
*Please use this unit with caution as you can accidentally export many high-res .png files if you trigger this unit with the Sequencer or Tick units.
➡️: export (trigger)
➡️: texture to be exported
The previous frame of VFX unit as a texture. You can connect this to the Textures unit to allow VFX unit to sample itself to draw graphics on top of its previous frame.
➡️: export (trigger)
➡️: texture to be exported
Load a .png or .jpg image on canvas. The image can be passed as a texture to the VFX shader when it is connected to an inlet of Textures unit.
➡️: width
➡️: height
➡️: opacity
Double click on the purple circle and use keyboard to edit text. Use this to write comments in your patch...
➡️: size
➡️: opacity
Load RayTone Graphics Assets (Image, Video, Webcam units) as textures to the GLSL fragment shader in the VFX unit. Use RAYTONE_TEXTURE(0-7) and RAYTONE_TEXTURE_RESOLUTION(0-7) (where the value in parentheses is the texture index starting at 0) in the fragment shader to read a texture and its resolution from RayTone.
*Only a single Textures Unit is allowed in a RayTone patch.
➡️: texture1
➡️: texture2
➡️: texture3
➡️: texture4
➡️: texture5
➡️: texture6
➡️: texture7
➡️: texture8
Load a GLSL fragment shader to display on canvas. Use RAYTONE_INLET(0-7) (where the value in parentheses is the inlet index starting at 0) in the fragment shader to read an inlet value from RayTone.
*Only a single VFX Unit is allowed in a RayTone patch.
➡️: inlet1
➡️: inlet2
➡️: inlet3
➡️: inlet4
➡️: inlet5
➡️: inlet6
➡️: inlet7
➡️: inlet8
Load an .mp4 video on canvas. The video can be passed as a texture to the VFX shader when it is connected to an inlet of Textures unit.
➡️: play trigger
➡️: playback rate (default: 1, max: 10)
➡️: playhead position in milliseconds (only set on play trigger)
➡️: loop ("on" if value is larger than 1)
➡️: width
➡️: height
➡️: opacity
Capture the default webcam device on OS as a dynamic image on canvas. The webcam can be passed as a texture to the VFX shader when it is connected to an inlet of Textures unit.
➡️: width
➡️: height
➡️: opacity
The following is a template GLSL fragment shader code that you can use with the VFX unit.
#version 410
//-----------------------------------------------------------------------------
//RAYTONE HEADER
uniform vec3 iResolution;
uniform float iTime;
uniform float inlets[8];
uniform sampler2D textures[8];
uniform vec3 textureResolutions[8];
#define RAYTONE_RESOLUTION iResolution
#define RAYTONE_TIME iTime
#define RAYTONE_INLET(i) inlets[i]
#define RAYTONE_TEXTURE(i) textures[i]
#define RAYTONE_TEXTURE_RESOLUTION(i) textureResolutions[i]
//-----------------------------------------------------------------------------
out vec4 fragColor;
void main()
{
// Define UV coordinates based on canvas resolution
vec2 uv = gl_FragCoord.xy / RAYTONE_RESOLUTION.xy;
// Read inlet 0 to create yellow columns
float r = sin(uv.x * RAYTONE_INLET(0) * 100);
float g = sin(uv.x * RAYTONE_INLET(0) * 100);
float b = uv.y * (sin(RAYTONE_TIME) * 0.5 + 0.5); // flashing blue
// Define texture coordinates based on its resolution
vec2 tex1_uv = gl_FragCoord.xy / RAYTONE_TEXTURE_RESOLUTION(0).xy;
// Sample texture
vec4 tex1 = texture(RAYTONE_TEXTURE(0), tex1_uv);
// Output is RGB + texture
fragColor = vec4(r, g, b, 1.0) + tex1;
}