HOWTO implement new openSMILE components:
=========================================

This manual is under heavy construction.....
It only contains basic hints to get you started


In the source directory some examples for various component types are provided, which you should use as a starting point. These files contain some helpful documentation as comments in the source.

To create your new component from an existing component or an example source file use the perl scipt 'clonecomp.pl':
>  perl clonecomp.pl <inputCompBase> <yourCompBase> <inputCompName> <yourCompName> 

(For a complete openSMILE class and component hierarchy, please refer to the file classes.txt)

Each component is a descendant of cSmileComponent. This base class encapsulates all the functionality required for accessing the configuration data, managing the configuration and finalisation process of all components, and running components ('ticking'). See smile_component.txt (TODO!) for more information on cSmileComponent and the complete component architecture of openSMILE.

Generally speaking, there are three basic types of components used in openSMILE:
 
 1. Data Sources  (cDataSource descendants, see exampleSource.hpp/cpp)
   
    A data source contains a writer sub-component (cDataWriter), which is responsible for writing data to exactly one level of the data memory (see cDataProcessor description below).
    Implement a descendant of THIS component if you want to add a new input format, e.g. MP3 or feature file import (HTK, ARFF, etc.) 

 2. Data Processors (cDataProcessor descendants, see exampleProcessor.hpp/cpp)

    A data processor contains both reader and writer components (cDataReader and cDataWriter). The general purpose of a data processor is to read data from the data memory (from one or more levels) and write data to one single level (NOTE: each writer has exclusive access to exactly on level, i.e. each level is written to by exactly one writer and thus by exactly one data processor or data source component).
   THIS component is the one you most likely want to inherit if you want to implement new FEATURES.
   Please also see below, for special kinds of data processors for common processing tasks!

 3. Data Sinks (cDataSink descendants, see exampleSink.hpp/cpp)

    A data sinks contains a reader sub-component (cDataReader), which is responsible for
    the 'read' interface to a specific data memory level (or multiple levels)
    Implement a descendant of THIS component, if you want to add support for more data output formats (e.g. sending data over a network, real-time visualisation of data via a GUI, etc.)


Since the data processors are very general components, two special descendants have been implemented:

cVectorProcessor:
  This class allows an easy frame by frame processing of data (mostly processing of feature frames in the spectral domain). Input framesize can be different from the output framesize, thus it is very flexible. Algorithms such as signal window function, FFT, Mfcc, Chroma, etc. are implemented using cVectorProcessor as base. See exampleVectorProcessor.hpp/cpp for an example to start with.

cWindowProcessor:
  This class allows processing of signal windows (e.g. filters, functionals, etc.).
  The main functionality provided, is automatic overlap of signal windows, i.e. for having access to past and future samples in a certain window, yet still offering the possibility of block processing for efficient algorithms. See preemphasis.cpp/hpp for an example.

cWinToVecProcessor:
  This class takes data from a signal window and produces a single value or vector of values (frame) for this window. You can specify an overlap (via frameStep and frameSize). This class is used for windowing the input wave-form signal, but can also be inherited for implementing data summaries (i.e. statistical functionals). See framer.cpp/hpp for an example implementation of a descendant class.



