Processing 3 & SuperCollider Interaction

I’m working on a SuperCollider, Processing 3 interaction. Whenever a certain frequency is played from a synth, a shape appears in the Processing window, but when the frequency is not being played, the shape does not appear on the screen. I would really appreciate any help. I have been working on this for a while. I have watched some tutorials on this, so my code is inspired by the tutorials. Here is what I have so far:

SuperCollider Code:

~bus1 = Bus.control(s);

~proc = NetAddr("127.0.0.1", 12321);


(
SynthDef.new(\synth, {
	arg freq, kbs;
	var env, sig;
	env = EnvGen.kr(Env([0,1,0], [0.01, 0.5]), doneAction:2);
	sig = Saw.ar(freq, 0.25)*env;
	Out.ar(kbs, sig.dup);
	Out.ar(0, sig.dup);
}).add;
)


OSCdef(\getfreq, {
	~proc.sendMsg("/freq1", ~bus1.getSynchronous.asFloat);
}, "/getfreq");


(
    Pbind(
	\instrument, \synth,
    \freq, Pseq([220.00, 329.63, 523.25, 329.63, 523.25, 329.63, 146.83, 220.00, 349.23, 220.00, 349.23, 220.00, 174.71, 261.63, 440.00, 261.63, 440.00, 261.63]*2, inf),
	\dur, Pseq([1/8], inf),
	\stretch, 1.5,
	\kbs, ~bus1,
	\out, 0,
).play;
)

Processing 3 Code:

import netP5.*;
import oscP5.*;

OscP5 osc;
NetAddress sc;


float color1 = 0.0;
float color2 = 0.0;
float color3 = 0.0;
float color4 = 0.0;
float color5 = 0.0;


void setup(){
  size(640, 480, P2D);
  background(0);
  
  osc = new OscP5(this, 12321);
  sc = new NetAddress("127.0.0.1", 57120);
  osc.plug(this, "newfreq", "/freq1");
}
  
  
void draw(){
  OscMessage msg = new OscMessage("/getfreq");
  osc.send(msg, sc);
    stroke(0, 255, 0);
    fill(color1);
    triangle(0, 0, 0, 50, 50,0); 
    stroke(0, 255, 0); 
    fill(color2); 
    triangle(0, 50, 50, 0, 50, 50); 
    stroke(0, 255, 0);
    fill(color3); 
    triangle(50, 0, 50, 50, 100, 0); 
    stroke(0, 255, 0); 
    fill(color4); 
    triangle(50, 50, 100, 0, 100, 50);
    stroke(0, 255, 0);
    fill(color5);
    triangle(100, 50, 100, 0, 150, 0); 
}
  
  
void newfreq (float rms){
  color1 = map(rms, 220, 220.1, 0.0, 255);
  color2 = map(rms, 261.63, 261.64, 0.0, 255);
  color3 = map(rms, 392, 393, 0.0, 255);
  color4 = map(rms, 164.81, 164.82, 0.0, 255);
  color5 = map(rms, 196, 197, 0.0, 255);
}

Hey,

What is the actual problem you are facing at? It seems normal that when the synth is not playing, you don’t draw something with processing…

I re-formatted my question in the SuperCollider forum that may be more concise. I apologize for the convoluted response, but it might help .

From SuperCollider forum:

"I’m trying to get SuperCollider to control animations in Processing 3 through OSC. Whenever a certain frequency is played from a synth, a shape appears in the Processing window, but when the frequency is not being played, the shape does not appear on the screen. The frequency would be controlling the color value of the shapes. For example, if a frequency of 220 is played, the color value will be 255. I’m wondering if I could send the frequencies from my Pbind as floating point number OSC messages to Processing 3 to control the animations? I’d really appreciate any help. I have found a useful example. Here’s code from the example I found, then below that is my code:

SuperCollider:

(
SynthDef(\blip, { | freq = 440, amp = 0.85, att = 0.01, rel = 0.06, ffreq = 1000 |
    var sig, env, lfo;
    sig = SinOsc.ar(freq.asFloat, 0, amp);
    env = EnvGen.ar(Env.perc(att, rel), doneAction:2);
    lfo = SinOsc.kr(rel * ffreq);

    Out.ar(0, Pan2.ar(RHPF.ar(sig*env, ffreq), SinOsc.kr(211*lfo)))
}).play;
)

Synth(\blip);

(
f = fork {
    loop {
        256 do: { arg i;
            n.sendMsg("/sc3p5", i.asFloat); // send OSC message to P5
            Synth(\blip, [\freq, 440+i, \ffreq, 1000+i*2]);
            ((i+1).reciprocal*2).wait;
        }
    }
};
)

Processing:

import oscP5.*;
import netP5.*;
OscP5 oscP5;

float x; // global variable

void setup() {
  size(400, 300);
  frameRate(24);
  background(0);
  smooth();

  OscProperties properties = new OscProperties();
  properties.setListeningPort(47120); // osc receive port (from sc)
  oscP5 = new OscP5(this, properties);
}

void oscEvent(OscMessage msg) {
  if (msg.checkAddrPattern("/sc3p5")) {
    x = msg.get(0).floatValue(); // receive floats from sc
  }
}

void draw() {
  background(x, x, 0);
  println("POST: ", x);
  // draw rect
  stroke(256-x/2, 256-x*abs(sin(x)), 256-x/4);
  strokeWeight(4);
  fill(256-x/2, 256-x, 256-x*abs(sin(x)));
  translate(width/2, height/2);
  rotate(x%64);
  rect(x%64, x%64, x*abs(sin(x))%128, x*abs(sin(x))%128, 6);
}

The code I have:
SuperCollider:


n = NetAddr("127.0.0.1", 47120);  // open 47120 on localhost server


(
SynthDef.new(\synth, {
	arg freq, kbs;
	var env, sig;
	env = EnvGen.kr(Env([0,1,0], [0.01, 0.5]), doneAction:2);
	sig = Saw.ar(freq, 0.25)*env;
	Out.ar(0, sig.dup);
}).add;
)


(
    Pbind(
	\instrument, \synth,
    \freq, Pseq([220.00, 329.63, 523.25, 329.63, 523.25, 329.63, 146.83, 220.00, 349.23, 220.00, 349.23, 220.00, 174.71, 261.63, 440.00, 261.63, 440.00, 261.63].asFloat, inf),
	\dur, Pseq([1/8], inf),
	\stretch, 1.5,
	\out, 0,
).play;
)

Processing:

import oscP5.*;
import netP5.*;
OscP5 oscP5;

float color1 = 0.0;
float color2 = 0.0;
float color3 = 0.0;
float color4 = 0.0;
float color5 = 0.0;

void setup() {
  size(400, 300);
  frameRate(24);
  background(0);
  smooth();

  OscProperties properties = new OscProperties();
  properties.setListeningPort(47120); // osc receive port (from sc)
  oscP5 = new OscP5(this, properties);
}

void oscEvent(OscMessage msg) {
  if (msg.checkAddrPattern("/sc3p5")) {
    color1 = msg.get(0).floatValue(); // receive floats from sc
  }
    if (msg.checkAddrPattern("/sc3p5")) {
    color2 = msg.get(0).floatValue(); // receive floats from sc
  }
    if (msg.checkAddrPattern("/sc3p5")) {
    color3 = msg.get(0).floatValue(); // receive floats from sc
  }
    if (msg.checkAddrPattern("/sc3p5")) {
    color4 = msg.get(0).floatValue(); // receive floats from sc
  }
    if (msg.checkAddrPattern("/sc3p5")) {
    color5 = msg.get(0).floatValue(); // receive floats from sc
  }
}

void draw() {
    stroke(0, 255, 0);
    fill(color1);
    triangle(0, 0, 0, 50, 50,0); 
    stroke(0, 255, 0); 
    fill(color2); 
    triangle(0, 50, 50, 0, 50, 50); 
    stroke(0, 255, 0);
    fill(color3); 
    triangle(50, 0, 50, 50, 100, 0); 
    stroke(0, 255, 0); 
    fill(color4); 
    triangle(50, 50, 100, 0, 100, 50);
    stroke(0, 255, 0);
    fill(color5);
    triangle(100, 50, 100, 0, 150, 0); 
}
2 Likes

Whenever a certain frequency is played from a synth, a shape appears in the Processing window, but when the frequency is not being played, the shape does not appear on the screen.

To answer your question more directly, I think you’re addressing this part. I may have poorly worded what I said there, but I’m just saying what I’m trying to get it to do. A synth plays a certain frequency that corresponds to a certain color, and when the frequency is not present, the color goes back to the original value, which I’d like to be 0.

The code I posted in the original message is far off the mark, I think. It doesn’t work, doesn’t do anything.

It seems that in your code, you are not sending Osc messages from SuperCollider to Processing. In the code above, they use :

n.sendMsg("/sc3p5", i.asFloat);

Also there’s this nice tutorial :

Ah, thanks.

I’ve seen that tutorial, but I’m trying to get SuperCollider talking to Processing, so the other way around.

I think you are running into a thread issue. I had a problem in an processing project with drawing in an oscMessage event method. Basically, you can’t, but you can work around it. See this topic: Stumped by something simple

Let me know if I can help…

1 Like