We will implement an example communication between two Cinder applications written in Cinder to illustrate how we can send and receive signals. Each of these two applications can be replaced by a non-Cinder application very easily.
We are going to use the Open Sound Control (OSC) messaging format, which is dedicated for communication between wide ranges of multimedia devices over the network. OSC uses UDP protocol, providing flexibility and performance. Each message consists of URL-like addresses and arguments of integer, float, or string type. The popularity of OSC makes it a great tool for connecting different environments or applications developed with different technologies over the network or even on the local machine.
While downloading the Cinder package we are also downloading four primary blocks. One of them is the osc
block located in the blocks
directory. First, we will add a new group to our XCode project root and name it Blocks
, and after that we will drag the osc
folder inside the Blocks
group. Be sure the Create groups for any added folders options and MainApp in the Add to targets section are checked.
We only need to include an src
from the osc
folders, so we will delete references to the lib
and samples
folders from our project tree. The final project structure should look like the following screenshot:
Now we have to add a path to the OSC
library file as another linker flag's position in your project's build settings:
$(CINDER_PATH)/blocks/osc/lib/macosx/osc.a
First we will cover instructions for the sender, and then for the listener.
We will implement an application that sends OSC messages.
#include "OSCSender.h"
osc::Sender
class, so let's declare the needed properties in the main class:osc::Sender mOSCSender; std::string mDestinationHost; int mDestinationPort; Vec2f mObjPosition;
setup
method:mDestinationHost = "localhost"; mDestinationPort = 3000; mOSCSender.setup(mDestinationHost, mDestinationPort);
mObjectPosition
to be the center of the window:mObjPosition = Vec2f(getWindowWidth()*0.5f, getWindowHeight()*0.5f);
mouseDrag
method, which includes two major operations—updating the object position according to the mouse position and sending the position information via OSC.void MainApp::mouseDrag(MouseEvent event) { mObjPosition.x = event.getX(); mObjPosition.y = event.getY(); osc::Message msg; msg.setAddress("/obj/position"); msg.addFloatArg(mObjPosition.x); msg.addFloatArg(mObjPosition.y); msg.setRemoteEndpoint(mDestinationHost, mDestinationPort); mOSCSender.sendMessage(msg); }
void MainApp::draw() { gl::clear(Color(0.1f, 0.1f, 0.1f)); gl::color(Color::white()); gl::drawStrokedCircle(mObjPosition, 50.f); }
We will implement an application that receives OSC
messages.
#include "OSCListener.h"
osc::Listener
class, so let's declare the required properties in the main class:osc::Listener mOSCListener; Vec2f mObjPosition;
setup
method, passing the port number for listening as a parameter:mOSCListener.setup(3000);
mObjectPosition
to be the center of the window:mObjPosition = Vec2f(getWindowWidth()*0.5f, getWindowHeight()*0.5f);
update
method, we will be listening for the incoming OSC
messages:void MainApp::update() { while (mOSCListener.hasWaitingMessages()) { osc::Message msg; mOSCListener.getNextMessage(&msg); if(msg.getAddress() == "/obj/position" && msg.getNumArgs() == 2 && msg.getArgType(0) == osc::TYPE_FLOAT && msg.getArgType(1) == osc::TYPE_FLOAT) { mObjPosition.x = msg.getArgAsFloat(0); mObjPosition.y = msg.getArgAsFloat(1); } } }
draw
method will be almost the same as the sender version, but instead of stroked circle we will draw a filled circle:void MainApp::draw() { gl::clear( Color( 0.1f, 0.1f, 0.1f ) ); gl::color(Color::white()); gl::drawSolidCircle(mObjPosition, 50.f); }
18.220.174.191