Skip to content

simpleoca#

Simpleoca is a small auxilliary library which is part of libaes70. It can optionally be used together with libaes70 to implement devices. It contains implementations of many standard AES70 classes.

Simpleoca is aimed at platforms with enough resources to use standard library features such as std::function. The general API for AES70 class implementations in simpleoca is to configure a given object, e.g. an instance of simpleoca::OcaGain using a corresponding settings object. The settings object contains initial values of properties and optional callbacks to handle property changes received from a controller.

As an example, the definition of simpleoca::OcaGainSettings is defined as:

namespace simpleoca
{
    struct OcaGainSettings
    {
      aes70::OcaString Role;
      aes70::OcaBoolean Enabled = true;

      std::function<aes70::OcaBoolean(aes70::OcaBoolean, aes70::OcaBoolean)>
          EnabledChanged;

      aes70::OcaFloat32 Gain = 0.0f;

      aes70::OcaFloat32 MinGain = 0.0f;
      aes70::OcaFloat32 MaxGain = 0.0f;

      std::function<aes70::OcaFloat32(aes70::OcaFloat32, aes70::OcaFloat32)>
          GainChanged;
    };
}

simpleoca is intended to be used with the dynamic_device APIs. A simple example for how to use it could look like this:

for (size_t i = 0; i < 4; i++) {
    auto block = device.create_block("Channel " + std::to_string(i+1));

    simpleoca::OcaGainSettings gainSettings;
    gainSettings.Role = "Gain";
    gainSettings.MinGain = -6.0f;
    gainSettings.MaxGain = 6.0f;
    gainSettings.onGainChanged = [=](float prevValue, float value) {
        std::cerr << "Channel " << (i+1)
                  << "gain changed to " << value << std::endl;
        return value;
    };
    block->create_child<simpleoca::OcaGain>(gainSettings);
}

The control classes have methods to update properties and callbacks. For instance, simpleoca::OcaGain defines UpdateGain(float value) which will update the gain property and send change notifications to all controllers.

simpleoca contains documentation comments which describe in detail how each implemented control class behaves. Some general design decisions:

  • The signature of change handlers is auto changedCallback(auto prevValue, auto value). The change handler can then return the resulting value. For example, if the new value should be used as-is it can simply be returned. If the change should be prevented, the prevValue could be returned. This is also a good place to implement clipping or other logic. Additionally, an exception of type aes70::device::error_status can be thrown, which will fail the property change with the given status code.

  • When a change handler is not specified (or set to nullptr), the corresponding setter will always return OcaStatus::NotImplemented.

  • Properties which have min max settings, the change handler is never called with values outside of this range. This is done by clamping values into the range min...max.

Integration#

simpleoca is a standard library with seperate source and header files. It comes with cmake support which should make integration into other cmake projects straightforward. Check the examples below for how this can be done.

Examples#

For an example for how to use the simpleoca library look at the example provided in examples/all_classes_simpleoca.

For an example application which uses simpleoca, check out our aes70-device-emulator development tool.