Setup OSC communication for Photoshop

Next Post →

Overview and Requirements

In this post, we’ll setup Photoshop to use OSC (Open Sound Control).

We’ll use a Generator plugin called Openbuttkiss, which gives OSC messages access to Photoshop’s API. More specifically, when an OSC message with an argument of 1 is recieved, the foreground and background colors are swapped. Utilized by this plugin is a Nodejs module that provides the protocols to communicate via OSC. I made the plugin to demonstrate this sort of integration at its most fundamental level; it is left simple and concise. Expansion will come later.

I used some code from Tom Krcha’s getting-started-plugin - this provided a good foundation for my plugin and the features I would add. Big thanks to him and the others out there that made great tutorials employing Photoshop-Generator and Nodejs:

The purpose of writing this post is to explain and understand the OSC implementation that is happening in my plugin. I’d like to clear up any areas of the code that are prone to confusion, and that may have caused myself some frustration.

To follow along, you’ll need:

Photoshop CC, Generator-Core, Node.js, Osculator, Openbuttkiss

Installation

  1. Download openbuttkiss.

  2. In terminal, cd to the plugin folder (openbuttkiss) and run npm install to download any dependencies.

  3. Follow one of the methods below to set up the plugin with a Photoshop Generator.

Built-in Generator

Place the plugin inside the Photoshop Plug-ins folder:

Applications/Adobe Photoshop CC/Plug-ins/Generator

Built-in Generator plugin location

Open Photoshop. Go to Photoshop > Preferences > Plug-ins and check Enable Generator. You may need to restart Photoshop for this to take effect.

External Generator

Run the plugin from a locally cloned generator-core library (think of this as our external generator, which exists outside of the Photoshop application). Don’t forget to npm install, to grab all the generator-core dependencies. My workflow when using this library consists of having all my plugins inside the generator-core plugins folder:

External Generator plugin location

In terminal, cd to generator-core and run:

node app.js -f test/plugins/openbuttkiss

This app.js contains all the magic needed to run our plugin. The plugin location is specified at the end of the command.

Photoshop can use Built-in and External Generators to process a plugin; each generator provides a slightly different workflow. Regardless of which generator is being used, the plugin should produce the same results. Be aware that conflicts may arise when using both internal and external generators. In my experience, I had to disable the built-in generator to properly run openbuttkiss with the external generator.

Read more on Photoshop Generators and the Generator Architecture.

Running

After completing the above steps, openbuttkiss should now be available for use. In Photoshop, select the plugin from the drop down menu:

File > Generate > openbuttkiss

Plugin being run by the Built-in Generator

built-in generator running our plugin

Plugin being run by an External Generator

external generator running our plugin

When selected, the plugin name in the Generate dropdown menu should be checked, telling us and Photoshop that it’s enabled. To disable the plugin, select it again.

Now that we’re running openbuttkiss, we are ready to send it some OSC action. We’ll need to use a program that can handle sending/recieving OSC messages. Here, I’ll be using Osculator, which is free and fully functional to download, minus the 20 second timeouts.

Configuring Osculator

  1. Open up Osculator.

  2. Go to View > Parameters, or click on the Parameters icon. This page stores any OSC addresses we plan on communicating to, with each address, being stored as a target. Under the OSC URL or choice from gear menu column, double click on the empty address slot of target #1. Type in:

    osc.udp://localhost:3333

    Osculator address

  3. Click the + symbol located in the bottom left corner of the Parameters page. Close the Parameters page.

  4. Go to Routing > Manually Create Message... Name it whatever you want and hit ok. A new message appears in the application window.

  5. Click the empty message parameter under the Event Type column, select OSC Routing from the dropdown menu.

  6. Click the empty message parameter under the Value column, select Đ from the dropdown menu.

Done!

Our new OSC message should now be targeting the address we specified earlier. We should now be able to send it to Photoshop. Do this by clicking the small grey box on the left hand side of the message we just created, it should flash green.

If everything went over smoothly, when we trigger the message in Osculator, we should see the foreground and background colors swap in Photoshop. Remember that openbuttkiss must be enabled in Photoshop.

Plugin Code

package.json

{
    "name": "openbuttkiss",
    "description": "osc-ps plugin",
    "version": "0.0.0",
    "main": "main.js",
    "generator-core-version": ">=1.0.0",
    "dependencies": {
        "node-osc": "0.2.1"
    },
    "devDependencies": {}
}

main.js

var oscR = require('node-osc'),

Retrieve the logic for receiving OSC messages. The logic comes from the node-osc dependency we installed earlier, which exists in the node_modules folder of our plugin.

oscServer = new oscR.Server(3333, '127.0.0.1'),

Create an osc server and assign it to the variable oscServer. Server initialization happens when we run the plugin from terminal, or, if using the internal/built-in Generator, whenever we start up Photoshop. Once we set up a listerner, our server will be able to recieve incoming osc messages at 127.0.0.1 (localhost), port 3333.

Don’t get the oscServer mixed up with our server listener, they are two different things.

toggler = 0,

Toggler gets assigned either a 0 or 1 based on the plugin’s menu-state - whether is is checked or unchecked.

psToFront = "app.bringToFront();";

Switch to Photoshop application. Bring it to the front of any other applications we have open. Must be passed to _generator.evaluateJSXString().

var colorFlip = "var fColor = app.foregroundColor;
    app.foregroundColor = app.backgroundColor;
    app.backgroundColor = fColor;";

Swap foreground and background colors. Both colorFlip and psToFront are extendscript code (.jsx) and must be handled differently than other javascript in main.js. They are passed through _generator.evaluateJSXString(). I got stuck on this when I first tried to use extendscript in my Generator plugins - Check out my issue at Github.

oscServer.on("message", function (msg, rinfo) {
    if(toggler==1 && msg[1]==1){
        actions();
    }
});

oscServer.on is the server’s listener - it listens for incoming osc messages. The plugin must be enabled at least once for the listener to initialize. After that, the server will always be listening, choosing whether or not to execute actions() based on the conditions of the if statement. If these conditions are not met, the message will still be recieved, but nothing will be done.

There are probebly other ways in which our plugin menu-state can influence our OSC server and server listener. To enable/disable these components, in accordance to our our menu-state, might be a better alternative to our current setup.

function actions(){
    _generator.evaluateJSXString(colorFlip);
    _generator.evaluateJSXString(psToFront);
}

Called from our oscServer.on, this function executes two things, colorFlip followed by our psToFront. Both of these are passed to _generator.evaluateJSXString().

if(checked==true) {
    toggler = 1;
    console.log("OSC enabled!");
} else {
    toggler = 0;
    console.log("OSC disabled!");
}

Inside the onMenuClicked() function. Each time the plugin’s menu-state changes, an if / else statement is executed, setting toggler to 0 or 1.

Understanding OSC Messages

Node-osc gives us access to different parts of our osc message.

The message bubbahjubbah, sent from Osculator to openbuttkiss, could be broken down like this:

bubbahjubbah transmits two arguments each time it is triggered

msg msg[0] msg[1]
[ ‘bubbahjubbah’, 1 ] bubbahjubbah 1
[ ‘bubbahjubbah’, 0 ] bubbahjubbah 0

I’m sure node-osc and other Nodejs OSC modules allow for a more elaborate parsing of messages. I haven’t fully explored Open Sound Control, and my involvment with it has not surpassed a most basic usage. The benefits of osc seem to be in its ability to develop a rich organization of flexible parameter names. Openbuttkiss keeps clear of all that. Its only interest is a message, of any address, with an argument of 1.

For more info on Open Sound Control: