Communicating with other software

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.

Getting ready

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.

Getting ready

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:

Getting ready

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

Tip

CINDER_PATH should be set as a user-defined setting in the build settings of your project and it should be the path to Cinder root directory.

How to do it...

First we will cover instructions for the sender, and then for the listener.

Sender

We will implement an application that sends OSC messages.

  1. We have to include an additional header file:
    #include "OSCSender.h"
  2. After that we can use the osc::Sender class, so let's declare the needed properties in the main class:
    osc::Sender mOSCSender;
    std::string mDestinationHost;
    int         mDestinationPort;
    
    Vec2f       mObjPosition;
  3. Now we have to set up our sender inside the setup method:
    mDestinationHost = "localhost";
    mDestinationPort = 3000;
    mOSCSender.setup(mDestinationHost, mDestinationPort);
  4. Set the default value for mObjectPosition to be the center of the window:
    mObjPosition = Vec2f(getWindowWidth()*0.5f,
                         getWindowHeight()*0.5f);
  5. We can now implement the 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);
    }
  6. The last thing we need to do is to draw a method just to visualize the position of the object:
    void MainApp::draw()
    {
      gl::clear(Color(0.1f, 0.1f, 0.1f));
        gl::color(Color::white());
        gl::drawStrokedCircle(mObjPosition, 50.f);
    }

Listener

We will implement an application that receives OSC messages.

  1. We have to include an additional header file:
    #include "OSCListener.h"
  2. After that we can use the osc::Listener class, so let's declare the required properties in the main class:
    osc::Listener  mOSCListener;
    Vec2f          mObjPosition;
  3. Now we have to set up our listener object inside the setup method, passing the port number for listening as a parameter:
    mOSCListener.setup(3000);
  4. And the default value for mObjectPosition to be the center of the window:
    mObjPosition = Vec2f(getWindowWidth()*0.5f,
                         getWindowHeight()*0.5f);
  5. Inside the 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);
            }
        }
    }
  6. Our 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);
    }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.174.191