Successful Live Coding with SuperCollider and Hydra via OSC?

Hello everyone! :wave:

I’m keen to explore the synergy between SuperCollider 's powerful audio synthesis and Hydra 's real-time visual live coding capabilities. I’m aiming for a cohesive audiovisual live coding performance setup.


Seeking Integration Examples

Has anyone here successfully integrated SuperCollider and Hydra for a live coding setup? I’m particularly looking for successful examples and advice on how to send OSC (Open Sound Control) messages from SuperCollider to control parameters within Hydra.

I understand Hydra can listen for OSC, but I’m struggling with the most efficient way to generate the messages from within my SuperCollider event structure.


SuperCollider Event Context

I’m currently generating rhythmic events using Tdef and dynamically spawning synths, similar to the pattern below.

The goal is to capture the specific parameters of these spawned synths (e.g., \freq , \amp , \sp ) and transmit them as an OSC message every time a synth is triggered, so Hydra can react to the audio events.

Here is the pattern I’m working with:

`Supercollider~a.clear

~a.play; ~a.awake_(false);
~a = {Splay.ar(SinOscFB.ar(\freq.ir(80)*[1,1.5],\fb.ir(2),\amp.ir(0.5)),\sp.ir(1),) * Env.perc(\atk.ir(0.05),\rel.ir(0.05),1,\cur.ir(-7) ).ar(2)}

~a1.clear
~a1 = Tdef(\a1, {

loop{ 
	~a.spawn([\freq, [80,90,100].choose, \fb, 1, \sp, [0,1].choose, \atk, 0.05, \rel,0.09,\amp, 0.3]); 
0.25.wait; 
	~a.spawn([\freq, [100,200,200].choose, \fb, 0.5, \sp, [0,1].choose, \atk, 0.05, \rel,0.09, \amp, 0.3]); 
0.25.wait; 
	~a.spawn([\freq, [200,300,400].choose, \fb, 0.5, \sp, [0,1].choose, \atk, 0.05, \rel,0.09,\amp, 0.3]); 
0.25.wait; 

}; 

});

~a1.play;
~a1.pause;
~a1.resume;`

The Specific OSC Question

How would I best integrate an OSC sender (using NetAddr ) into this Tdef structure?

For example, I want to send a message like /trigger/synth with the parameters (freq , fb , amp , etc.) to a specific port (e.g., 8000 ) every time ~a.spawn is called.

`Supercollider// Conceptual OSC sending integration
~addr = NetAddr(“127.0.0.1”, 8000); // Assuming Hydra is on localhost, port 8000

// … inside the Tdef loop …
// Before 0.25.wait:
~addr.sendMsg(‘/trigger/synth’, [freqValue, fbValue, ampValue, …]);
// …`

Have you done this successfully? I’m looking for the most robust way to ensure the OSC messages are synchronized with the synth spawns without causing timing issues in the Tdef .

Any shared successful setups, code examples, or general tips would be greatly appreciated! :pray:

Thanks in advance for the help!

There are so many ways to do this. I’m going to assume you want to keep using tdef and the code you have now, there are other options that are worth being aware of because they have musical implications…

To keep the code you already have, I’d use object prototyping to redefine ~a.

~a = (
   \fn: { ...ugen code... },
   \netAddr: NetAddr(...),
   \spawn: { |self ...args, kwargs| 
      self.netAddr.sendMsg('/osc/addr', 'freq', kwargs.asEvent.freq);
      self[/fn].spawn.(kwargs);
   }
);

~a.spawn(freq: 440);

This would let you keep the same style of code you have with only minor changes.

Alternatively you might consider doing some kind of machine listening and send the results of that to, often the relationship between synth argument and what we actually hear is very complex and not convincingly visualised with just the argument alone.

1 Like