/ Reference / Fiddle Runtime

abc2midi guide .. abc cheatsheet
Fiddle Runtime .. Fiddle Resources
Extending Fiddle .. Installing Fiddle
General MIDI .. MIDI CC .. MIDI notes
Box2D API .. Tidal Cheatsheet
Banklist File .. Sample TOC File
Audio Troubleshooting


Wherein we give a concise account of Fiddle's runtime classes.

Fiddle Runtime is the collection of .ck and .yaml files that come with the Fiddle distribution and that underpin the ChucK Live feature set.

If you are interested in extending the Fiddle Runtime, this information is for you. Otherwise, perhaps not.

Fiddle Runtime source is found at (fiddle install)/resources/Fiddle/chuckruntime.

Right-click to navigate to a place in this doc.

Vocabulary

Fiddle App is the running instance of Fiddle GUI application.

Fiddle Runtime is the collection of over 100 .ck files that, when loaded into a ChucK session, allow for control and monitoring of ChucK by Fiddle App.

Fiddle Node is both the graphical representation in Fiddle App and the concrete instance of a Fiddle Runtime class running in a ChucK session.

ChucK Session is an instance of ChucK running over the course of your performance. Usually you only need a single ChucK session active but you can have multiple sessions running simultaneously.

ChucK Shred is ChucK's version of a programatic thread of execution. In a typical performance, tens of shreds are active and operating simultaneously.

Bootstrap

_bootstrap.ck is used to bootstrap the entire Fiddle runtime. Only after the successful loading of this program does Fiddle App correctly interoperate with a running ChucK session.

Fiddle

A single instance of the Fiddle class acts as the liaison between the Fiddle App and running instances of chuck. Fiddle extends the OscListener class and this means that we employ OSC for our intercommunication layer. It is over this channel that parameter updates from Fiddle App to the ChucK session occur. The same mechanism is used to deliver ChucK updates for Fiddle App that provide feedback and plotter data.

Controller

IController is the base class for all subclasses that require a separate ChucK shred for independent operation. The key function of a Controller is to "drive" Controllables. To do this, we require Fiddle to spork our subclass' Play method. IController is the base class for eg Player, TimeKeeper, ccSampler, ccGenerator, etc.

Player

Players control instruments by delivering note events to instruments with the correct timing. When a note is sustained, a player's shred is effectively idling for a note's duration. Embedded control-changes like pitch-bend are also delivered to an instrument by its player. When Player is connected to multiple instruments it manages polyphony (even MPE) by routing note and control-change events to the appropriate instrument.

TimeKeeper

Timekeeping is an opt-in feature. Classes that keep track of TimeKeeper state are said to be in sync. When you play notes on your MIDI device you can try to be in sync or not, there is no enforcement there. The same can be said of procedural nodes that disregard TimeKeeper. Player opts-in to TimeKeeper by

public class TimeKeeper
{
    // beats per measure, beat-type (ie: 4/4 or 3/4 or 3/8)
    int Signature[2];
    float bpm;

    // durations (changed when bpm changes)
    dur Measure, Beat;  
    dur HalfNote, QuarterNote, EighthNote, SixteenthNote;

    TimeLocation CurrentTime; // composition time coordinatates
}

TimeLocation

public class TimeLocation
{
    0=>int Measure; // indexed from 0
    0=>float Beat;
    0=>float TotalBeats;
    t_zero => time Time;
    ... methods...
}

CCController

Like Players, CCControllers, control other node behaviors by running in a separate shred and delivering control change (CC) messages to the downstream controllable nodes.

Unlike Players, CCControllers have no knowledge or support for NoteStreams. You can think of the CCController as a generalization of the LFO. CCControllers typically deliver updates to one or more named control channel at a rate of your choice. Control Change signals can be delivered to any number of downstream controllables. At right you can see a CCController subclass, CCGenerator, sending BPM updates to both the TimeKeeper (to produce tempo changes) as well as the CCPlot node.

Other CCControllers of note:

You can implement your own controller by extending the base class and overriding:

fun float ComputeControl(int iter, int clientId); // override

It's likely that your custom controller will require synchronization with other aspects of your composition. The TimeKeeper and TimeLocation classes expose the current global time in a number of representations. ChucK has a cross-shred notification feature, called Events. A system of custom extensions could exploit this capability in interesting and powerful ways.

Controllable

Controllable is an interface for delivering Control Change messages to a receiver. Most classes directly or indirectly extend this class. A few need to apply a bit of trickiness to become controllable. This is due to the fact that ChucK doesn't currently support multiple inheritance. To get around this, we employ pretty simple trick.
The idea is to create a lightweight Controllable subclass that knows how to delegate messages to its target.

Instrument

The Fiddle Runtime comprises a large number of Instruments. That said, custom instruments are always desireable and if you find yourself extending Fiddle, it's likely you'll be developing an instrument. Keep in mind that you can accomplish this task without any programming via the ADSR or Envelope nodes. But if you want something more exotic or procedural, you've come to the right place.

Most instruments are monophonic and inherit from the Instrument base class. They can easily be placed anywhere in a stereo soundfield via downstream Channel or Effects nodes. In contrast, some instruments want to conflate stereo position with control events and thus opt to inherit from the Instrument2 base class. GrainBuf is one such example.

Instruments minimally override these methods. Other methods are available for override but we'll refer you to the source for more details.

fun float Freq(float f) ;
fun void NoteOn(float velocity);
fun void NoteOff(float velocity);
fun void ControlChange(string name, float value);

Most of ChucK's built-in instruments have been wrapped in Instrument subclasses to deliver the benefits of ChucK Live.

NoteStream

Like Instrument, NoteStream is another excellent opportunity for customization. A NoteStream represents a canned or procedural sequence of notes active over a time range.

Here are some NoteStream subclasses that ship with Fiddle organized by category:

Live
Canned
Procedural

These tree broad categories and their constituents provide a solid foundation for composition, but clearly there's no end to the variety of notestreams that can be conceived.

Here's all you need to implement your own NoteStream subclass:

public class MyNoteStream extends NoteStream
{
    fun Note NextNote(TimeLocation loc)
    {
        // your code here..
    }
}

The Note class is central to this interface. It embodies the information needed to allow the downstream Player to perform its duties.

Notes come in two flavors: live (aka untimed) and timed either of which can be requested through the Note interface:

public class Note
{
    fun void Reset(); // to a 1-beat rest

    // pitch is in midi scale, -1 means rest

    fun int Init(float pitch, float nbeats, float v);
    fun void LiveNoteOn(float pitch, float v);
    fun void LiveNoteOff(float pitch, float v);

    ControlChange @cc; // can piggy-back with notes
}

Using LiveNotes in your NoteStream incurs the responsibility that the note event be delivered at the right time. This implies that your node will idle, either in another blocking method (like waiting for a MIDI or OSC event) or by chucking to now yourself. It also requires that you deliver the associated LiveNoteOff. Failing to do so may result in "stuck notes", depending on the downstream instrument.

Notes can be decorated with modifiers by assigning a ControlChange instance to the note's cc parameter. If you have no decorations to apply you should do this

null => Note.cc;

Here's the ControlChange class in its entirety:

public class ControlChange
{
    string name;
    int id;
    float value;
    int midinote; // for polyphonic aftertouch (not MPE)
}

Channel

The Channel base class is the primary means to control a chain of audio processing stages. It comes equipped with dry and wet ports and a Mix parameter. It automatically routes the input signal to the output through the dry port. The wet port depends on a per-subclass signal flow.

Subclasses should do this:

this.inlet => myeffect => this.wet;

It should be noted that to support Effects Chains, Fiddle's code generator automatically generates Channel subclasses.

From the outside world the inlet and outlet keywords are Pan2 nodes which support gain and pan parameters.

Channels can be arranged "hierarchically" and at least one instance should be be routed to the dac, either manually or via the ToDAC param/method. In this way, a graph can include a master signal control as well as any number of Channels (groups and/or channels).

We currently don't anticipate the need to extend this class manually but, who knows? If there is a will, there is a way.

FX

The FX base class accepts one or more Signals as input and combines them into a single outlet. To subclass FX you simply need to assign and object reference to this.fx:

/* controllable Gain node */
public class GainFX extends FX
{
    Gain gain @=> this.fx;
}

Filter

The Filter base class accepts a single signal as input and produces a filtered output signal. Standard parameters for Quality, Cutoff and Gain are supported.

public class HighPass extends Filter
{
    HPF hpf @=> this.filt;
}

Workspace

The Workspace class is responsible for resolving resource references according to your current workspace settings. It is a static, singlton class. There may not be value in subclassing it, but if your .ck code needs to resolve an asset file reference, here's how:

SndBuf b => dac;
Workspace.ResolvePath("mySound.wav") => string fullpath;
fullpath => b.read;
home .. topics .. interface .. reference .. examples .. tipjar