I'm writing a node in C, and, within my node implementation, I'd like to pass values to another node, execute it, and get its results. How can I do that?

Comments

As of Vuo 1.1, this is

smokris's picture
Submitted by

As of Vuo 1.1, this is possible, but it's fragile — if the target node's ports change (if a port is added or removed, or if the port order changes), your node's invocation will misbehave or crash. In the future, we'd like to add an easier and more robust interface for invoking nodes.

  • Start by looking at the source code of the node you'd like to invoke:
    • Copy the function prototypes for all the node*() functions (e.g., nodeEvent()).
    • Trim the VuoInputData(), VuoInputEvent(), VuoOutputData(), and VuoInstanceData() decorations down to just the type name and the argument name. The type name for VuoInputEvent() is bool. For VuoOutputData() arguments, add an extra *, since they're passed by reference.
    • Prefix each function name with the node class name, with the dots changed to underscores, followed by two underscores.
  • Add the prototypes to your node.
  • In the VuoModuleMetadata, indicate that your node depends on the node you're invoking. For example, "dependencies": ["vuo.motion.wave"]

Example: Calculate Loudness node (stateless)

Add this prototypes to your node just below the #include lines:

void vuo_audio_analyze_loudness__nodeEvent(VuoAudioSamples samples, VuoReal *loudness);

Then you can invoke the node as follows:

VuoAudioSamples samples = …;
VuoReal loudness;
vuo_audio_analyze_loudness__nodeEvent(samples, &loudness);
VLog("The loudness of these samples is %g", loudness);

Example: Wave node (stateful)

Add these prototypes to your node just below the #include lines:

void *vuo_motion_wave__nodeInstanceInit(void);
void vuo_motion_wave__nodeInstanceEvent(VuoReal time, VuoWave wave, bool waveEvent, VuoReal period, bool periodEvent, VuoReal center, VuoReal amplitude, VuoReal phase, VuoReal *value, void **instanceData);
void vuo_motion_wave__nodeInstanceFini(void **instanceData);

Then you can instantiate and invoke the node as follows:

void *waveInstance = vuo_motion_wave__nodeInstanceInit();
for (double t = 0; t <= 10; ++t)
{
    VuoReal value;
    vuo_motion_wave__nodeInstanceEvent(t, VuoWave_Sine, false, 10, false, 0, 1, 0, &value, &waveInstance);
    VLog("At time %f, the wave value is %f", t, value);
}
vuo_motion_wave__nodeInstanceFini(&waveInstance);