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.
Nice work Andres!
Andres, thank you so much for working on this! Your brilliance is inspiring.
Andres, were you ever able to patch up the memory leak in this Syphon build?
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.
No prob, thanks for the response! And sorry for the double post– browser bug.
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.
Hola Alba, ya te contesté en el foro :-)
Pingback: Kinect Processing Syphon and Resolume | Tangible Experiments
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)
yes, unfortunately the syphon library is broken in 2.0 final (https://github.com/processing/processing/issues/1860). But, hopefully, this will be taken care of in the next point release. For the time being you can use 2.0b8 or 2.0b9 in order to run syphon.
any way to declare variables input splitters from Processing(server) to Resolume(client)?
the syphon server in processing only sends out frame data… but you could send other information using the OSC protocol (the oscP5 library might help).
Is there a way to parse the width and height of the incoming frames into SyphonClient?
yes, the client.getGraphics() returns a PGraphics object, which has width/height you can access
Thanks!