Syphon Client working in Processing   16 comments

Syphon is an OSX framework to share frames between applications. The authors of Syphon, Tom Butterworth and Anton Marini, made it very easy to create Syphon plugins for other languages, frameworks, VJ’ing and mapping tools, etc. So a while ago I wrote a simple Processing library that allowed to send frames out. This was quite useful, but still missing half of the Syphon functionality. With some additional coding, we were able to add the client part, and I just put the new version (0.4) of the Syphon-Processing library up for download (it requires Processing 2.0a4 or newer).

The client and server functions were tested on both OSX Snow Leopard and Lion (keep in mind that OSX 10.6 is the minimum requirement for Syphon). Below, some screenshots showing Processing-Quartz inter-communication!

Quartz (client) to Processing (server)

Processing (server) to Quartz (client)

The code to setup up Syphon servers and clients in Processing is simple. To send out frames, we need to create a server with a name we choose:

void setup() {
  size(400,400, P3D);
  server = new SyphonServer(this, "Processing Frame Server");
  ...
}

void draw() {
  ...
  server.sendImage(img);
}

The argument for sendImage() can be either a PImage or a P3D PGraphics object. Also, note that the main renderer for the sketch also needs to be P3D, otherwise the library won’t work.

In order to receive frames, we need to setup a client in a similar way:

public void setup() {
  size(480, 340, P3D);
  client = new SyphonClient(this, "Simple Server");
  ...
}

void draw() {
  if (client.available()) {
    canvas = client.getGraphics(pg);
    ...
  }
}

The second argument for the client constructor is just the name of the running Syphon server we want to get the frames from. The getGraphics() method only accepts as argument a PGraphics object, again created with the P3D renderer. The SyphonClient class also defines a getImage() method that accepts PImages, but it doesn’t work in this release. This will be completed in future versions. I hope you find this library find useful, please leave your comments below, or use the Processing and Syphon forums to report issues, make comments, and also to describe projects made with it.

Posted February 21, 2012 by ac in Programming

Tagged with , , , , ,

16 responses to “Syphon Client working in Processing

Subscribe to comments with RSS.

  1. Nice work Andres!

  2. Andres, thank you so much for working on this! Your brilliance is inspiring.

  3. Andres, were you ever able to patch up the memory leak in this Syphon build?

  4. Andres, were you ever able to patch up the memory leak in this build of Syphon?

    • Hi, fixing the memory leak in the latest version of the syphon library is in the “to-do” list. However, I’m busy with other projects at the moment, but will look at it as soon as I get get the chance.

  5. hi Andres, I have processing 2.0b7 and your last library version.
    It’s cool that works in Processing 2.0, but before all OPENGL changes I could write my sketch directly in draw and after send all to Syphon,
    Is it could be possible?

    like this:

    void draw(){
    draw stuff
    capture screen to canvas
    send canvas to Syphon
    }

    thanks for all your work to the processing community!

    Alba.

  6. Pingback: Kinect Processing Syphon and Resolume | Tangible Experiments

  7. Amazing! It worked for me on Processing 2.0b8. On Processing 2.0 though it gives me following error:
    Already called beginDraw()
    Exception in thread “AWT-EventQueue-0” java.lang.IllegalAccessError: tried to access method processing.opengl.PGraphicsOpenGL.getTexture(Lprocessing/core/PImage;)Lprocessing/opengl/Texture; from class codeanticode.syphon.SyphonServer
    at codeanticode.syphon.SyphonServer.sendImage(Unknown Source)
    at SendFrames.draw(SendFrames.java:42)
    at processing.core.PApplet.handleDraw(PApplet.java:2270)
    at processing.opengl.PGL$PGLListener.display(PGL.java:2643)
    at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:576)
    at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:561)
    at javax.media.opengl.awt.GLCanvas$7.run(GLCanvas.java:1054)
    at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1024)
    at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:899)
    at javax.media.opengl.awt.GLCanvas$8.run(GLCanvas.java:1065)
    at javax.media.opengl.Threading.invoke(Threading.java:193)
    at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:483)
    at javax.media.opengl.awt.GLCanvas.paint(GLCanvas.java:537)
    at sun.awt.RepaintArea.paintComponent(RepaintArea.java:276)
    at sun.awt.RepaintArea.paint(RepaintArea.java:241)
    at apple.awt.ComponentModel.handleEvent(ComponentModel.java:263)
    at java.awt.Component.dispatchEventImpl(Component.java:4820)
    at java.awt.Component.dispatchEvent(Component.java:4572)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:710)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:669)
    at java.awt.EventQueue$2.run(EventQueue.java:667)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
    at java.awt.EventQueue$3.run(EventQueue.java:683)
    at java.awt.EventQueue$3.run(EventQueue.java:681)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:680)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
    java.lang.RuntimeException: java.lang.IllegalAccessError: tried to access method processing.opengl.PGraphicsOpenGL.getTexture(Lprocessing/core/PImage;)Lprocessing/opengl/Texture; from class codeanticode.syphon.SyphonServer
    at com.jogamp.common.util.awt.AWTEDTExecutor.invoke(AWTEDTExecutor.java:58)
    at jogamp.opengl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:100)
    at jogamp.opengl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:205)
    at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:172)
    at javax.media.opengl.Threading.invoke(Threading.java:191)
    at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:483)
    at processing.opengl.PGL.requestDraw(PGL.java:1155)
    at processing.opengl.PGraphicsOpenGL.requestDraw(PGraphicsOpenGL.java:1602)
    at processing.core.PApplet.run(PApplet.java:2141)
    at java.lang.Thread.run(Thread.java:680)
    Caused by: java.lang.IllegalAccessError: tried to access method processing.opengl.PGraphicsOpenGL.getTexture(Lprocessing/core/PImage;)Lprocessing/opengl/Texture; from class codeanticode.syphon.SyphonServer
    at codeanticode.syphon.SyphonServer.sendImage(Unknown Source)
    at SendFrames.draw(SendFrames.java:42)
    at processing.core.PApplet.handleDraw(PApplet.java:2270)
    at processing.opengl.PGL$PGLListener.display(PGL.java:2643)
    at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:576)
    at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:561)
    at javax.media.opengl.awt.GLCanvas$7.run(GLCanvas.java:1054)
    at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1024)
    at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:899)
    at javax.media.opengl.awt.GLCanvas$8.run(GLCanvas.java:1065)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:708)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:669)
    at java.awt.EventQueue$2.run(EventQueue.java:667)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:678)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

  8. any way to declare variables input splitters from Processing(server) to Resolume(client)?

  9. Is there a way to parse the width and height of the incoming frames into SyphonClient?

Leave a comment