PiPo - Plugin Interface for Processing Objects
PiPo - Plugin Interface for Processing Objects Documentation

PiPo is a simple plugin API for modules processing streams of multi-dimensional data such as audio, audio descriptors, or gesture and motion data. The current version of the interface is limited to unary operations. Each PiPo module receives and produces a single stream. The elements of a stream are time-tagged or regularly sampled scalars, vectors, or two-dimensional matrices.

More information http://imtr.ircam.fr/imtr/PiPo

PiPo API Overview

The PiPo API consists of an abstract class of a few virtual methods for propagating stream attributes (see below), frames, and additional processing control through a series of modules:

Implementation of a New PiPo Module

The minimal module must derive from the class PiPo and implement at least the streamAttributes and frames methods:

If the module can produce additional output data after the end of the input data, it must implement finalize, from within which more calls to propagateFrames can be made, followed by a mandatory call to propagateFinalize.

If the module keeps internal state or buffering, it should implement the reset method to put itself into a clean state.

The utility function signalError can be used to pass an error message to the host.

Module Attributes or Parameters

The template class PiPo::Attr permits to define scalar, enum, or variable or fixed size vector attributes of a pipo module that are exposed to the host environment.

The are initialised in the module constructor with a short name, a description, a flag if a change of value means the fundamental stream parameters must be reset (if true, streamAttributes will be called again for the whole chain), and a default value.

Their value can be queried in streamAttributes or frames (in real-time hosts, an attributes value can change over time) with PiPo::Attr::get().

Example of a Minimal PiPo Module

class PiPoGain : public PiPo
{
private:
std::vector<PiPoValue> buffer;
public:
PiPoGain (Parent *parent, PiPo *receiver = NULL)
: PiPo(parent, receiver),
factor(this, "factor", "Gain Factor", false, 1.0)
{ }
~PiPoGain (void)
{ }
int streamAttributes (bool hasTimeTags, double rate, double offset,
unsigned int width, unsigned int height,
const char **labels, bool hasVarSize,
double domain, unsigned int maxFrames)
{
// A general pipo can not work in place, we need to create an output buffer
buffer.resize(width * height * maxFrames);
return propagateStreamAttributes(hasTimeTags, rate, offset, width, height,
labels, hasVarSize, domain, maxFrames);
}
int frames (double time, double weight, PiPoValue *values,
unsigned int size, unsigned int num)
{
double f = factor.get(); // get gain factor here, as it could change while running
PiPoValue *ptr = &buffer[0];
for (unsigned int i = 0; i < num; i++)
{
for (unsigned int j = 0; j < size; j++)
ptr[j] = values[j] * f;
ptr += size;
values += size;
}
return propagateFrames(time, weight, &buffer[0], size, num);
}
};

PiPo API Details

PiPo Stream Attributes

PiPo streams are a sequences of frames characterized by a set of attributes. A PiPo module defines the attributes of its output stream when receiving the attributes of the input stream.

Each module can configure its internal state depending on the attributes of the input stream (e.g. memory allocation and pre-calculated state variables) before propagating its output stream attributes to the next module.

This way, the attributes of the input stream are propagated through a series of PiPo modules before starting the actual stream processing.

In summary, a PiPo stream is described by the following attributes: