Data engines
goofi has three engines, and each runs its nodes by different rules: what triggers a node, how fast it runs, and what language it is written in. Every node belongs to one engine, and so does every data type.
Signal engine
The signal engine is for signal processing. It is event driven: a producer node sends a data packet downstream, and each packet that arrives triggers the receiving node to process the new data. Nodes run asynchronously, each on its own thread and at its own rate, so a slow analysis never holds up a fast stream. It supports Python and Rust nodes.
Array
Numerical data in any number of dimensions. By convention, a time series keeps time in its last dimension. All arrays are float32.
String
Text passed between nodes. A number written as text is still a string: convert it before using it in a calculation.
Table
A map from unique string keys to values, each an array, a string or another table. It bundles several messages into one group, and nests as deep as you need.
Audio engine
The audio engine is for sound. It is clock driven: the sound device asks for one block of 64 samples at a time, and every node in the graph processes that block in turn, in topological order on a single thread, so the whole graph runs in lockstep at the device’s sample rate. It supports Rust nodes and VST3 plugins, and a signal crosses into it through a bridge node such as SignalIn.
Audio
Samples processed by the audio engine, with one or more channels. Use an audio output node to send it to your speakers or headphones.
Graphics engine
The graphics engine is for images. It is frame driven: a clock ticks 30 times a second, and on each tick the whole graph renders once on the GPU, node after node, into shared textures. A node is a WGSL fragment shader, or a Rust or Python producer that uploads pixels for the shaders to work on. A signal comes in through ArrayIn, as pixels, a line plot or a trajectory.
Texture
An image held on the GPU for graphics processing. Connect textures to compatible graphics inputs and open a viewer to see the result.