Open Lighting Architecture  0.9.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
C++ Client API Tutorial

Table of Contents

Overview

This page introduces the OLA Client API, and provides sample programs to send and receive DMX512 data from olad.

Building

Once OLA is installed on your system, the examples can be built with:

g++ example.cpp $(pkg-config --cflags --libs libola)

Streaming Client DMX512 Transmit

The quickest way to get started is by using ola::client::StreamingClient (ola::StreamingClient in releases < 0.9.0). The program below sends 100 frames of DMX data to the olad server on universe 1. The frames are sent 25ms apart which gives a frame rate of 40 fps.

Each frame consists of 512 DMX data slots. The first slot is incremented by one each frame, the other slots are always 0. This produces the following DMX frames:

  Time (ms)  DMX Data
       0     0,0,0,0,.....
      25     1,0,0,0,.....
      50     2,0,0,0,.....
      75     3,0,0,0,.....
    ....
    2475     100,0,0,0,.....

For releases 0.9.0 onwards, you should use code such as:

#include <stdlib.h>
#include <unistd.h>
#include <ola/DmxBuffer.h>
#include <ola/Logging.h>
#include <iostream>
using std::cout;
using std::endl;
int main(int, char *[]) {
unsigned int universe = 1; // universe to use for sending data
// turn on OLA logging
ola::DmxBuffer buffer; // A DmxBuffer to hold the data.
buffer.Blackout(); // Set all channels to 0
// Create a new client.
// Setup the client, this connects to the server
if (!ola_client.Setup()) {
std::cerr << "Setup failed" << endl;
exit(1);
}
// Send 100 frames to the server. Increment slot (channel) 0 each time a
// frame is sent.
for (unsigned int i = 0; i < 100; i++) {
buffer.SetChannel(0, i);
if (!ola_client.SendDmx(universe, buffer)) {
cout << "Send DMX failed" << endl;
exit(1);
}
usleep(25000); // sleep for 25ms between frames.
}
return 0;
}

For releases prior to 0.9.0, use

#include <stdlib.h>
#include <unistd.h>
#include <ola/DmxBuffer.h>
#include <ola/Logging.h>
#include <iostream>
using std::cout;
using std::endl;
int main(int, char *[]) {
unsigned int universe = 1; // universe to use for sending data
// turn on OLA logging
ola::DmxBuffer buffer; // A DmxBuffer to hold the data.
buffer.Blackout(); // Set all channels to 0
// Create a new client.
// Setup the client, this connects to the server
if (!ola_client.Setup()) {
std::cerr << "Setup failed" << endl;
exit(1);
}
// Send 100 frames to the server. Increment slot (channel) 0 each time a
// frame is sent.
for (unsigned int i = 0; i < 100; i++) {
buffer.SetChannel(0, i);
if (!ola_client.SendDmx(universe, buffer)) {
cout << "Send DMX failed" << endl;
exit(1);
}
usleep(20000); // sleep for 25ms between frames.
}
return 0;
}

While ola::StreamingClient is easy to use it has the drawback that it can only send DMX512 data. It's not possible to retrieve information (like the active universes etc.) from olad using the StreamingClient.

OLA Client DMX512 Transmit

The ola::client::OlaClient provides a much richer interface for interacting with the server. However, because of this it's slightly harder to use.

The following code behaves thes same as the Streaming Client DMX512 Transmit example.

For releases 0.9.0 onwards, you should use code such as:

#include <ola/DmxBuffer.h>
#include <ola/io/SelectServer.h>
#include <ola/Logging.h>
#include <ola/Callback.h>
using std::cout;
using std::endl;
bool SendData(ola::client::OlaClientWrapper *wrapper) {
static unsigned int universe = 1;
static unsigned int i = 0;
buffer.Blackout();
buffer.SetChannel(0, i);
wrapper->GetClient()->SendDMX(universe, buffer, ola::client::SendDMXArgs());
if (++i == 100) {
wrapper->GetSelectServer()->Terminate();
}
return true;
}
int main(int, char *[]) {
if (!wrapper.Setup()) {
std::cerr << "Setup failed" << endl;
exit(1);
}
// Create a timeout and register it with the SelectServer
ss->RegisterRepeatingTimeout(25, ola::NewCallback(&SendData, &wrapper));
// Start the main loop
ss->Run();
}

For releases prior to 0.9.0, use

#include <ola/DmxBuffer.h>
#include <ola/io/SelectServer.h>
#include <ola/Logging.h>
#include <ola/OlaClientWrapper.h>
#include <ola/Callback.h>
using std::cout;
using std::endl;
bool SendData(ola::OlaCallbackClientWrapper *wrapper) {
static unsigned int universe = 1;
static unsigned int i = 0;
buffer.Blackout();
buffer.SetChannel(0, i);
wrapper->GetClient()->SendDmx(universe, buffer);
if (++i == 100) {
wrapper->GetSelectServer()->Terminate();
}
return true;
}
int main(int, char *[]) {
if (!wrapper.Setup()) {
std::cerr << "Setup failed" << endl;
exit(1);
}
// Create a timeout and register it with the SelectServer
ss->RegisterRepeatingTimeout(25, ola::NewCallback(&SendData, &wrapper));
// Start the main loop
ss->Run();
}

DMX512 Receive

For releases 0.9.0 onwards, you should use code such as:

#include <ola/DmxBuffer.h>
#include <ola/Logging.h>
#include <string>
static const unsigned int UNIVERSE = 1;
// Called when universe registration completes.
void RegisterComplete(const ola::client::Result& result) {
if (!result.Success()) {
OLA_WARN << "Failed to register universe: " << result.Error();
}
}
// Called when new DMX data arrives.
void NewDmx(const ola::client::DMXMetadata &metadata,
const ola::DmxBuffer &data) {
std::cout << "Received " << data.Size()
<< " channels for universe " << metadata.universe
<< ", priority " << static_cast<int>(metadata.priority)
<< std::endl;
}
int main() {
if (!wrapper.Setup())
exit(1);
ola::client::OlaClient *client = wrapper.GetClient();
// Set the callback and register our interest in this universe
client->SetDMXCallback(ola::NewCallback(&NewDmx));
ola::NewSingleCallback(&RegisterComplete));
wrapper.GetSelectServer()->Run();
}

For releases prior to 0.9.0, use

#include <ola/DmxBuffer.h>
#include <ola/Logging.h>
#include <ola/OlaClientWrapper.h>
#include <string>
static const unsigned int UNIVERSE = 1;
// Called when universe registration completes.
void RegisterComplete(const std::string& error) {
if (!error.empty()) {
OLA_WARN << "Failed to register universe";
}
}
// Called when new DMX data arrives.
void NewDmx(unsigned int universe,
uint8_t priority,
const ola::DmxBuffer &data,
const std::string &error) {
if (error.empty()) {
OLA_INFO << "Received " << data.Size()
<< " channels for universe " << universe
<< ", priority " << static_cast<int>(priority);
} else {
OLA_WARN << "Receive failed: " << error;
}
}
int main() {
if (!wrapper.Setup())
exit(1);
ola::OlaCallbackClient *client = wrapper.GetClient();
// Set the callback and register our interest in this universe
client->SetDmxCallback(ola::NewCallback(&NewDmx));
client->RegisterUniverse(
UNIVERSE, ola::REGISTER, ola::NewSingleCallback(&RegisterComplete));
wrapper.GetSelectServer()->Run();
}