Geddei::SubProcessor Class Reference
[Geddei's core classes.]

Base class that defines a single stateless Geddei signal data processing object. More...

#include <subprocessor.h>

Collaboration diagram for Geddei::SubProcessor:

Collaboration graph
[legend]
List of all members.
class DomProcessor

Public Member Functions

virtual ~SubProcessor ()

Protected Member Functions

virtual void initFromProperties (const Properties &properties)=0
const uint multiplicity () const
virtual void paintProcessor (QPainter &p)
virtual void processChunk (const BufferDatas &in, BufferDatas &out) const
virtual void processChunks (const BufferDatas &in, BufferDatas &out, const uint chunks) const
void setupIO (const uint numInputs=1, const uint numOutputs=1, const uint samplesIn=1, const uint samplesStep=1, const uint samplesOut=1)
void setupVisual (const uint width=50, const uint height=30, const uint redrawPeriod=0)
virtual PropertiesInfo specifyProperties () const
 SubProcessor (const QString &type, const MultiplicityType &multi=NotMulti)
virtual const bool verifyAndSpecifyTypes (const SignalTypeRefs &inTypes, SignalTypeRefs &outTypes)=0

Friends

class Combination
class ProcessorForwarder
class xSCoupling

Detailed Description

Base class that defines a single stateless Geddei signal data processing object.

Author:
Gav Wood <gav@cs.york.ac.uk>
The SubProcessor class is similar in profession to the Processor class. It may be utilised to the same ends. However, as the name may suggest, it trades some flexibility of the Processor class for simplicity and better performance in some scenarios (e.g. parallelisation).

There are far fewer methods open to you for reimplementation in this class and perhaps the biggest difference is how you define what it does. Rather than being given a method in which you may do anything, in this class you specify at initialisation time what size of a chunk of input you want and size of a chunk of output that will produce. Each chunk must be disassociated with any others and thus independent. This makes the SubProcessor object "stateless".

You may also notice that there are (essentially) no methods for public use. This is because SubProcessors (unlike Processors), on their own, are not useful for forming Geddei processing networks. Each SubProcessor must be encapsulated in a DomProcessor object. Each DomProcessor must have at least one SubProcessor object and is associated with only one type of SubProcessor, meaning that no other types of SubProcessor may be used with it.

DomProcessors have all the neccessary external interface methods as Processor, along with a few more custom ones.

Many of the SubProcessor's virtual methods are actually quite similar to those of the same name in the Processor class. initFromProperties(), verifyAndSpecifyTypes() and specifyProperties() are all the same, and setupIO() is very similar but with extra additions to declate the chunk input/output sizes.

Exactly one of processChunk() and processChunks() needs to be implemented: processChunk() is the simpler of the two allowing you to specify the input to output process as a single event. processChunks gives you, the developer, slightly more scope for optimisation allowing you to keep an internal state between multiple consecutive chunks. Obviously, use of this state cannot be relied upon for correct creation of the outputs, but if the answers to a previous chunk's calculation may be used to speed up a later chunk's calculation, this allows it.

Like the Processor class, SubProcessors support a feature called multiplicity. This allows a SubProcessor to leave undefined the exact number of inputs or outputs it has until the point of connection. In some circumstances this can be implied from its forward or backward connections. A constraint imposed by multiplicity is that all inputs and outputs must be of equivanent SignalTypes.

A simple example of a multiplicitive SubProcessor would be a "Sum" class, that has a multiplicitive input and a single output. It would simply add together a sample from each of the inputs to give the sum as an output. The number of inputs could change automatically depending upon how many sources were connected via. a MultiProcessor.

See also:
DomProcessor

MultiProcessor


Constructor & Destructor Documentation

Geddei::SubProcessor::SubProcessor ( const QString &  type,
const MultiplicityType &  multi = NotMulti 
) [protected]

SubProcessor constructor - use this when subclassing.

Parameters:
type This must be set to the name of the subclass.
multi The type of multiplicity this SubProcessor supports.

virtual Geddei::SubProcessor::~SubProcessor (  )  [inline, virtual]

Basic destructor.


Member Function Documentation

virtual void Geddei::SubProcessor::initFromProperties ( const Properties properties  )  [protected, pure virtual]

Initialises from the given properties. Should call setupIO() (and setupVisual() too, really) at least.

Any neccessary preprocessing can be done here, such as lookup table construction. This is a more useful place to do it than the constructor since you are given the property list here. You are guaranteed that this will be called before processChunk() or processChunks().

Parameters:
properties The given Properties for the SubProcessor to be initialised with.

const uint Geddei::SubProcessor::multiplicity (  )  const [inline, protected]

Determine the multiplicity of the connection. Only valid after setupIO() has has been called.

Returns:
The number of outputs in the case of an Output Multiplicitive object or the number of inputs in the case of an Input Multiplicitive object. Undefined is given otherwise.

void Geddei::SubProcessor::paintProcessor ( QPainter &  p  )  [protected, virtual]

Reimplement for to define how the SubProcessor should be drawn visually.

Parameters:
p The painting canvas onto which the visual may be drawn.
See also:
setupVisual()

void Geddei::SubProcessor::processChunk ( const BufferDatas in,
BufferDatas out 
) const [protected, virtual]

Reimplement to specify how to process a chunk of data.

Either this *or* processChunks() *must* be reimplemented.

Parameters:
in The input BufferData objects as a BufferDatas object, which acts similarly to an array of BufferData objects.
out An output BufferDatas object into which the results may be placed. You can treat is as a preallocated array of BufferData objects. Each BufferData object has also been preallocated to the exact size requested with setupIO().
See also:
processChunks()

void Geddei::SubProcessor::processChunks ( const BufferDatas in,
BufferDatas out,
const uint  chunks 
) const [protected, virtual]

Reimplement to specify how to process a chunk of data. With this method several chunks may be processed at once. Though the results must not depend on data other that that of their corresponding input, some SubProcessors may find it advantageous to be able to process multiple consecutive chunks together. This methods allows that.

Note:
Either this *or* processChunk() *must* be reimplemented.
Parameters:
in The input BufferData objects as a BufferDatas object, which acts similarly to an array of BufferData objects.
out An output BufferDatas object into which the results may be placed. You can treat is as a preallocated array of BufferData objects. Each BufferData object has also been preallocated to the exact size requested with setupIO().
chunks The number of chunks worth of data that each BufferData object contains. If samplesStep is less than samplesIn in setupIO, then care must be taken to read the data correctly, since chunks will be naturally overlapped to save bandwidth.
See also:
processChunk()

void Geddei::SubProcessor::setupIO ( const uint  numInputs = 1,
const uint  numOutputs = 1,
const uint  samplesIn = 1,
const uint  samplesStep = 1,
const uint  samplesOut = 1 
) [protected]

Call from initFromProperties(). Use it to set up the number of inputs/outputs, and the chunking parameters.

The shown defaults apply (even if you don't call setupIO), but you should call it anyway with full parameter spec for code readability if nothing else. Don't count on this behaviour for later versions.

The defaults imply a single sample for input will correspond to a single sample of output and each sample will be used exactly once, and there would be only one input and one output exhibiting this behaviour. Changing samplesIn to 2 would mean the 2 samples in would correspond to one sample out and that each ionput chunk would overlap by 50%, meaning that generally each sample would be used twice.

Parameters:
numInputs The number of input connection ports. This must be > 0. In the case of an input multiplicative SubProcessor, you may use Undefined to leave it for the connection to determine.
numOutputs The number of output connection ports. This must be > 0. In the case of an output multiplicative SubProcessor, you may use Undefined to leave if for the connection to determine.
samplesIn The number of samples for an input chunk. This must be >= samplesStep. If not it will be incresed to samplesStep. (If you're interested, the reason for this is that the plunging code works less efficiently otherwise.)
samplesStep The number of samples between consecutive starts of input chunks.
samplesOut The number of samples in the output chunks.
See also:
setupVisual()

void Geddei::SubProcessor::setupVisual ( const uint  width = 50,
const uint  height = 30,
const uint  redrawPeriod = 0 
) [protected]

Call this from initFromProperties to initialise the visual properties of the SubProcessor.

If this is not called, the size will default to 50x30 and no redraw.

Parameters:
width The width of the drawing canvas. Should be a multiple of 10.
height The height of the drawing canvas. Should be a multiple of 10.
redrawPeriod The rate for which the processor's visual should be redrawn in milliseconds. A value of zero means no explicit redraw.
See also:
setupIO() paintProcessor()

PropertiesInfo Geddei::SubProcessor::specifyProperties (  )  const [protected, virtual]

Reimplement to provide property specifications and default values for this SubProcessor.

Returns:
The Properties object that contains the property definitions and defaults.

virtual const bool Geddei::SubProcessor::verifyAndSpecifyTypes ( const SignalTypeRefs inTypes,
SignalTypeRefs outTypes 
) [protected, pure virtual]

Reimplement to restrict signal types this class can handle, and define signaltypes it will output.

Examples of correct usage:

 outTypes[0] = new Wave(2600.0); 
 outTypes[1] = inTypes[0]->copy(); 

TIP: Don't forget inTypes is const, so if you're dynamic_cast<...>'ing a member, you'll have to cast it something else const!

Parameters:
inTypes An array-like type populated with the input types of the connections. If the Processor is declared as a MultiIn, then you are guaranteed that all input types are the same basic class (parameters may be different); you don't need an extra test.
outTypes An array-like type to contain the output types of the connections. They are all initially null, and if this method returns true, they must be defined. The array is large enough to store all the connections' types in. If the Processor is declared as a MultiOut, then you only have to define the first type. Any entries left undefined will be populated by copies of the first entry. They must all be of the same basic class.
Returns:
true if inTypes is valid and outTypes is populated correctly.
See also:
proxyVSTypes(), for internal development.


The documentation for this class was generated from the following files:
Generated on Fri Nov 10 21:58:38 2006 for Exscalibar by  doxygen 1.5.1