A little simplicity with syphon

In order to not have to write the syphon code over and over I created a class to grab the display and send it.

    import codeanticode.syphon.*;
    class SFD{
      public PGraphics canvas;
      public SyphonServer server;
      PApplet that;
      SFD(PApplet tthat){
        that = tthat;
        canvas = createGraphics(that.width, that.height, P3D);
        // Create syhpon server to send frames out.
        server = new SyphonServer(that, "Processing Syphon");
      }

      void update(){
        that.loadPixels();
        canvas.loadPixels();
        for(int i=0;i<that.pixels.length;i++){
          canvas.pixels[i] = that.pixels[i];
        }
        canvas.updatePixels();
        server.sendImage(canvas);
      }
    }

then in the main

SFD send;//as a global
send = new SFD(this);//in setup();
send.update();//in draw()

hope this helps someone

Tagged:

Comments

  • send.update(); goes after everything you want to send

  • Thanks!!!! This is working a charm from the Processing IDE and it's much more convenient as a solution than before. I was trying to find a way using toxiclibs and the ToxicLibsSupport to do something similar. But this is much simpler :)

  • edited November 2013

    np, if you are using opengl in any way, it seems the image gets flipped.... sometimes. I really cant figure out why. to counteract this I made the following

     for(int x = 0; x < that.width; x++) {
          for(int y = 0; y < that.height; y++) {
              canvas.pixels[((that.height-y-1)*that.width+x)] = that.pixels[y*that.width+x];
          }
        }
    
  • Thanks will be using that if i encounter the flipping.

    By the way, do you manage to get it working using the Eclipse IDE? I get an error message every time that says: "java.lang.UnsatisfiedLinkError: no JSyphon in java.library.path" I have however added both Syphon.jar and JSyphon.jar to my buildpath. I really don't understand why it would work in the processing IDE and why it simply doesn't in Eclipse... Maybe it's worth posting a thread of its own for that?

  • I'm just using the processing IDE.

  • It would probably be faster if you used arrayCopy(that.pixels, canvas.pixels) instead of the for(...){...} loop.

  • granted, and I did not think about that, but is there an easy way to read the pixels in backwards, when using OPENGL as the renderer, I get a flipped image in VDMX, which is my primary use for messing with syphon in the first place

  • there are probably a couple of places where I could use that though, cheers!

  • adrock42, thank you for this class! It saved my day :)

    I'm curious is it possible to send multiple Syphon streams from one application?

    As far as I understand your code, it grabs screen pixel by pixel and sends its to Syphon. But what if I need many outputs and don't need Processing screen display at all? (maybe it can save some resources)

    Now I just launch many Processing instances, but it feels like wrong solution.

    I've tried to use PGraphics class, but I can't do all I can with "normal" approach. Like I load images from bitmap files, and they are displayed in Processing output, but not displayed in Syphon stream.

  • No library found for codeanticode.syphon Libraries must be installed in a folder named 'libraries' inside the 'sketchbook' folder.

    where should I get the "codeanticode.syphon" ? I apprieate that you can give me this!

    my email : godisachinese2@gmail.com

  • @dandaka you most likely could. I have not tried multiple streams out of processing, I have done multiple streams out of VDMX. I think what you are describing is a headless Syphon server to just serve up an image, and I dont think Syphon is the best tool for that. The idea behind syphon is to connect two applications that are working on an image. I use it to create visuals in processing that are audio reactive and pipe them into VDMX for live visual performance.

    It is also possible to grab the one stream out from many applications. All of these would still take up more resources because Syphon works on the video card. Go have a read at the syphon site (syphon.v002.info/) for more info

    @changhai download the library here https://code.google.com/p/syphon-implementations/downloads/list

    unzip it and put the Syphon folder in the libraries folder in the Sketchbook folder. You can find out your Sketchbook folder from the preferences in Processing.

    Restart Processing and use the menu item Sketch>Import Library>Syphon.

  • @adrock42 my use case is pretty close to yours. I want to generate audio reactive visuals. I need multiple Syphon streams for following cases:

    1. One stream to make audio reactive animated textures for 3D mesh or simple masked output.
    2. Another stream to make MIDI reactive masks in Resolume (plain BW images).

    Where do you get inspiration for your visuals?

  • My inspiration comes from my dreams and what I see everyday. I try to tell a story with my visuals.

    With what you are describing, I would make the server name a variable

    import codeanticode.syphon.*;
    class SFD{
      public PGraphics canvas;
      public SyphonServer server;
      PApplet that;
      SFD(PApplet tthat, String name){
        that = tthat;
        canvas = createGraphics(that.width, that.height, P3D);
        // Create syhpon server to send frames out.
        server = new SyphonServer(that, name);
      }
    
      void update(){
        that.loadPixels();
        canvas.loadPixels();
        for(int i=0;i<that.pixels.length;i++){
          canvas.pixels[i] = that.pixels[i];
        }
        canvas.updatePixels();
        server.sendImage(canvas);
      }
    }
    

    and then when you create the objects

    send = new SFD(this,"audio");//in setup();
    send = new SFD(this, "midi");//in setup();
    

    but I hope you have some power in your computer to back it up. Especially if you want to have both of those streams running together, as I assume the midi mask is going to be masking the audio reactive visuals. What are you using for VJ software? In VDMX you simply add each Syphon server to the media bin as a video clip. All of the servers available will be there if you right click the media bin > add built in source > and select the server

  • I use Resolume, same way as you describe with VDMX. So far latest MBP works pretty nice on these tasks. Can't be more happier with it.

    Here's my code for my task.

    import codeanticode.syphon.*;
    PGraphics canvas1;
    PGraphics canvas2;
    SyphonServer server;
    SyphonServer server2;
    
    PImage pi[] = new PImage[2];
    
    void setup() {
        // load images
        for (int i=0; i<=1; i++) {
            pi[i] = loadImage("1280x1024/"+i+".png");
        }
    
        size(1280, 1024, P3D);
        canvas1 = createGraphics(1280, 1024, P3D);
        canvas2 = createGraphics(1280, 1024, P3D);
    
        // Create syhpon server to send frames out.
        server = new SyphonServer(this, "Processing Syphon");
        server2 = new SyphonServer(this, "Processing Syphon 2");
    }
    
    void draw() {
        // some code to blend two images to create nice output
        PImage img = createImage(1280, 1024, RGB);
        img.blend(pi[0], 0, 0, 1280, 1024, 0, 0, 1280, 1024, ADD);
        img.blend(pi[1], 0, 0, 1280, 1024, 0, 0, 1280, 1024, ADD);
    
        canvas1.background(#ff9900);
        // Display image
        image(img, 0, 0);
        // Send image to Syphon
        server.sendImage(img);
        // Send image to Syphon
        server2.sendImage(canvas1);
        // Send image to Syphon
    }   
    
  • what about just making two processing sketches, one for the audio reactive and one for the midi reactive

    1. Also I've found this function https://github.com/Syphon/Processing/blob/master/Processing_2_0/examples/SendScreen/SendScreen.pde

    That should do similar things to your class (grab screen and send to Syphon). Doesn't seem to work for me with error:

    The function sendScreen() does not exist.

    1. Do you experience flipping of image with Syphon output? Seems like a bug, don't it?
  • Yeah, its possible to create two sketches. But they start to share (=duplicate) settings and code, and I like to keep it DRY and in one place.

  • I get flipping sometimes. I think it has something to do with using OPENGL as the renderer, and it might only happen in VDMX.

    i think sendImage needs to be used instead of sendScreen, but the sendScreen function in the source is

    public void sendScreen() {
        sendImage(pg);    
      }
    

    where pg is the screen, so yeah it does the same thing, maybe the dev hasnt updated the library with his new code from github. here is the source for the lib https://github.com/Syphon/Processing/blob/master/Processing_2_0/src/codeanticode/syphon/SyphonServer.java

  • frame rate is really low :S

  • edited January 2014

    works fine for me, might be your machine.

  • Very nice class for Syphon I think use your class in me next release of Romanesco Project, because like you say it's so boring to write canvas.function() all the time.

    Thx for the trick

  • i have not had time to check with the latest processing release, but I think they fixed the openGL flip that I had accounted for so this will work better arrayCopy(that.pixels, canvas.pixels)

  • work fine with P211

  • Has anybody been able to create a syphon server using Eclipse IDE / Proclipsing? I can't find any tips on the net that solve the problem of getting crappy exceptions like this one - http://pastebin.com/PRcGQx3c. Needless to say that it works perfectly when I use the Processing app, and many thanks for Syphon!

    Any help would be highly appreciated.

  • @adrock42 Thank you alot. Very much appreciated; a great help.

  • Thank you for contributing this class, this is super handy!

  • Thanks a lot for this class. Helps me with my teaching! Props.

  • edited December 2014

    Hi.

    I'm encountering the following error when trying to add your code in my ketch to use the syphon server class (using Processing 2.2.1 on Mac OSX 10.7.5)

    ClassCastException: processing.core.PGraphics3D cannot be cast to processing.opengl.PGraphicsOpenGL

    (same message with other renderers too..)

    I see most of you manage to get it work, and I'm not using classes so much yet, so maybe I'm missing something obvious.. Any idea to help me out if you have ever encountered this message ?

    Thanks in advance,

  • edited December 2014

    ClassCastException: processing.core.PGraphics3D cannot be cast to processing.opengl.PGraphicsOpenGL

    • Class PGraphics3D isn't part of "processing.core" package anymore.
    • It is now part of "processing.opengl" just like class PGraphicsOpenGL.
    • Actually, PGraphics3D is a subclass of PGraphicsOpenGL, which in turn inherits from "processing.core"'s PGraphics & PImage.

    https://github.com/processing/processing/tree/master/core/src/processing/opengl
    https://github.com/processing/processing/tree/master/core/src/processing/core

  • Thanks for replying, @GoToLoop. I need to understand how this should be reflected in my code. So far, I modified the class, trying to call PGraphics3D instead of PGraphics :

        class SFD{
          public PGraphics3D canvas;
          public SyphonServer server;
          PApplet that;
          SFD(PApplet tthat){
            that = tthat;
            canvas = createGraphics(that.width, that.height, P3D);
            // Create syhpon server to send frames out.
              server = new SyphonServer(that,"Processing Syphon");
          }
    
          void update(){
            that.loadPixels();
            canvas.loadPixels();
            for(int i=0;i<that.pixels.length;i++){
              canvas.pixels[i] = that.pixels[i];
            }
            canvas.updatePixels();
            server.sendImage(canvas);
          }
        }
    

    but processing returns the message "The type PGraphics3D is ambiguous." and won't execute the program.

    Thanks again in advance if you can help me understand better.

  • "The type PGraphics3D is ambiguous."

    It means there's more than 1 class called PGraphics3D in your sketch somehow!
    That's wrong b/c no 3rd-party library should name their own classes as 1 of the existing Processing's classes!

    Nonetheless we can still fully specify which 1 we wish by prefixing their fully package name:
    processing.opengl.PGraphics3D canvas;

  • hmm. I guess what's happening is that I'm using the same libraries set with processing 2 as I was using in Processing 1.5.

    This kind of things wouldn't happen if I keep a distinct one for each, I suppose ?

    Because, now it only gives me a new error :

    "cannot convert from PGraphics to PGraphics3D"

  • "cannot convert from PGraphics to PGraphics3D"

    Function createGraphics() returns a PGraphics reference type.
    Either store it in a PGraphics variable or (cast) it to something else:
    PGraphics3D pg3d = (PGraphics3D) createGraphics(width, height, P3D);

  • I have found this class implemtation of a syphon instance runs much slower than if you code it in by hand.

    Any idea why?

  • I'm not sure, i'm not a PGraphics expert but I think you can use canvas.loadPixels(); just in the constructor once and leave it out of the update method.

  • Okay, I will try that soon. I like the class implentation (way easier than wrapping everything in a canvas.xxx();) but it can be too slow for some sketches.

  • I checked and the loadPixels was not needed for the canvas (only 1 time so the pixel array exists).

    If you just want to send the main frame you don't have to create a PGraphics. This is a lot faster:

    import codeanticode.syphon.*;
    
    Syphon syphon;
    
    void setup() {
      size(500, 500, P3D);
    
    
      syphon = new Syphon(this, "dsfsf"); 
    }
    
    void draw() {
      background(255);
      fill(255, 0, 0);
      ellipse(noise(0.1*(frameCount+100))*width, noise(0.1*(frameCount+200))*height, noise(0.1*(frameCount+300))*100, noise(0.1*(frameCount+400))*100);
      syphon.send(); 
    }
    
    
    class Syphon {
    
      SyphonServer server;
    
      PApplet p;
    
      Syphon(PApplet p, String name){
        this.p = p;
        server = new SyphonServer(p, name);
      }
    
      void send(){
         send(p.g);
      }
    
      void send(PGraphics g){
         server.sendImage(g);
      }  
    
    }
    

    For the rest I advice not to name PApplet 'that'. It's very undescriptive. Most libraries name it 'p'. Also, what does SDF stand for? The S for Spyhon but the rest?

    It's a nice idea your working on.

  • So stoked on trying this out! Thanks @clankill3r

  • @clankill3r

    I am only getting the first frame sent to the Syphon Client. The sketch runs as expected but I am only getting the first frame sent and then it pauses.

    Any ideas?

  • Your on a pc I assume cause I didn't have that for a mac. Try loadPixels(); I recommend to not put that in the send method for reasons I will not type on a tablet.

  • what's syphon

  • here's some more info: http://syphon.v002.info/

  • Thank you!

  • edited July 2015

    Was struggling with implementing Syphon and this helped so much! Thanks @adrock42!

  • edited September 2015

    @clankill3r Your great code is broken now with the last update of syphon for Processing 3.0b6, I hope there is new amazing code :)

    class Syphon {
      SyphonServer server;
      PApplet p;
      Syphon(PApplet p, String name){
        this.p = p;
        server = new SyphonServer(p, name);
      }
      void send(){
         send(p.g);
      }
      void send(PGraphics g){
         server.sendImage(g);
      } 
    }
    
  • Has anyone tried to implement syphon to eclipse or intellij and has it worked?

Sign In or Register to comment.