name: Energy : public AlgorithmBase
synopsis:

>     g++ [flags ...] file ... -l /isip/tools/lib/$ISIP_BINARY/lib_algo.a

>     #include <Energy.h>

>     Energy(ALGORITHM algorithm = DEF_ALGORITHM, IMPLEMENTATION implementation = DEF_IMPLEMENTATION, float floor);
>     boolean eq(const Energy& arg);
>     boolean setAlgorithm(ALGORITHM algorithm);
>     boolean setFloor(float floor);

quick start:

>     Energy egy;
>     VectorFloat input(L"1, 0, -1");
>     VectorFloat output;
>     egy.setAlgorithm(Energy::IDENTITY);
>     egy.compute(output, input);

description:
The Energy class is used to compute the energy and power of a signal. Two good historical references for different ways to define and compute the energy of a signal are:

L. Rabiner and R. Schafer, Digital Processing of Speech Signals, Prentice-Hall, Englewood Cliffs, New Jersey, USA, pp. 116, 1976.

J. Picone, "Signal Modeling Techniques in Speech Recognition", IEEE Proceedings, vol. 81, no. 9, pp. 1215-1247, September 1993.

This class currently supports two algorithm choices: SUM and FILTER. These are described in detail below. Several scaling modes are supported as implementation choices including dB and RMS, both popular in engineering. The implementation choices for the algorithm choice SUM, along with the available scaling options, are shown below:
The FILTER algorithm processes the squared signal through a user-defined filter:

This filter can be written as:

The filter can be specified by the user using the setFilter() method.
The same implementation choices available for SUM apply to FILTER, even though users most often will want to use the IDENTITY implementation for this algorithm choice.
dependencies:

- AlgorithmBase
- CircularDelayLine

public constants:

- define the class name:

      static const String CLASS_NAME = L"Energy";

- define the algorithm choices:

      enum ALGORITHM { SUM = 0, FILTER, DEF_ALGORITHM = SUM };

- define the implementation choices:

      enum IMPLEMENTATION { IDENTITY = 0, LOG, DB, POWER, LOG_POWER, DB_POWER, RMS, LOG_RMS, DB_RMS, DEF_IMPLEMENTATION = IDENTITY };

- define the static NameMap objects:

      static const NameMap ALGO_MAP(L"SUM, FILTER");

      static const NameMap IMPL_MAP(L"IDENTITY, LOG, DB, POWER, LOG_POWER, DB_POWER, RMS, LOG_RMS, DB_RMS");

- define i/o related constants:

      static const String DEF_PARAM = L"";

      static const String PARAM_ALGORITHM = L"algorithm";

      static const String PARAM_IMPLEMENTATION = L"implementation";

      static const String PARAM_FLOOR = L"floor";

      static const String PARAM_MA_COEF = L"ma_coef";

      static const String PARAM_AR_COEF = L"ar_coef";

- define default value(s) of the class data:

      static const float DEF_FLOOR = 0;

- define default values for the filter coefficients:

      const VectorFloat Energy::DEF_MA_COEF(L"1");

      const VectorFloat Energy::DEF_AR_COEF(L"1");

- define default argument(s):

      static const AlgorithmData::COEF_TYPE DEF_COEF_TYPE = AlgorithmData::DEF_CTYPE;

error codes:

- error code indicating Energy class general error:

      static const long ERR = 70500;

protected data:

- data common to all algorithms and implementations:
  - define an algorithm name:

        ALGORITHM algorithm_d;

  - define an implementation name:

        IMPLEMENTATION implementation_d;

  - define an energy floor: limits the minimum value of energy (extremely useful when performing log operations)

        Float floor_d;

  - static memory manager:

        static MemoryManager mgr_d;

- algorithm and implementation specific variables:
  - algorithm: FILTER
    implementation: all
    - define parameters related to the FILTER mode: these allow a causal linear constant coefficient filter to be implemented

          VectorFloat ma_coef_d;

          VectorFloat ar_coef_d;

          Vector< CircularDelayLine<Float> > ma_mem_d;

          Vector< CircularDelayLine<Float> > ar_mem_d;

required public methods:

- static methods:

      static const String& name();

      static boolean diagnose(Integral::DEBUG debug_level);

- debug methods: setDebug method is inherited from base class

      boolean debug(const unichar* message) const;

- destructor/constructor(s):

      ~Energy();

      Energy(ALGORITHM algorithm = DEF_ALGORITHM, IMPLEMENTATION implementation = DEF_IMPLEMENTATION, float floor);

      Energy(const Energy& arg);

- assign methods:

      boolean assign(const Energy& arg);

- operator= methods:

      Energy& operator= (const Energy& arg);

- i/o methods:

      long sofSize() const;

      boolean read(Sof& sof, long tag, const String& name = CLASS_NAME);

      boolean write(Sof& sof, long tag, const String& name = CLASS_NAME) const;

      boolean readData(Sof& sof, const String& pname = DEF_PARAM, long size = SofParser::FULL_OBJECT, boolean param = true, boolean nested = false);

      boolean writeData(Sof& sof, const String& pname = DEF_PARAM) const;

- equality methods:

      boolean eq(const Energy& arg) const;

- memory management methods:

      static void* operator new(size_t size);

      static void* operator new[](size_t size);

      static void operator delete(void* ptr);

      static void operator delete[](void* ptr);

      static boolean setGrowSize(long grow_size);

      boolean clear(Integral::CMODE ctype = Integral::DEF_CMODE);

class-specific public methods:

- set methods:

      boolean setAlgorithm(ALGORITHM algorithm);

      boolean setImplementation(IMPLEMENTATION implementation);

      boolean setFloor(float floor = DEF_FLOOR);

      boolean setFilter(VectorFloat& ma_coef_a, VectorFloat& ar_coef_a);

      boolean set(ALGORITHM algorithm = DEF_ALGORITHM, IMPLEMENTATION implementation = DEF_IMPLEMENTATION, float floor = DEF_FLOOR);

- get methods:

      ALGORITHM getAlgorithm() const;

      IMPLEMENTATION getImplementation() const;

      float getFloor() const;

      float getFilter(VectorFloat& ma_coef_a, VectorFloat& ar_coef_a) const;

      boolean get(ALGORITHM& algorithm, IMPLEMENTATION& implementation, float& order);

- computational methods:

      boolean compute(VectorFloat& output, const VectorFloat& input, AlgorithmData::COEF_TYPE input_coef_type = DEF_COEF_TYPE, long index = DEF_CHANNEL_INDEX);

      boolean compute(VectorFloat& output, const VectorComplexFloat& input, AlgorithmData::COEF_TYPE input_coef_type = DEF_COEF_TYPE, long index = DEF_CHANNEL_INDEX);

- AlgorithmBase interface contract methods:

      boolean assign(const AlgorithmBase& arg);

      boolean eq(const AlgorithmBase& arg) const;

      const String& className() const;

      boolean init();

      boolean apply(Vector<AlgorithmData>& output, const Vector<AlgorithmData>& input);

      boolean setParser(SofParser* parser);

private methods:

- summation i/o methods:

      boolean readDataSum(Sof& sof, const String& pname, long size = SofParser::FULL_OBJECT, boolean param = true, boolean nested = false);

      boolean writeDataSum(Sof& sof, const String& pname) const;

- filter i/o methods:

      boolean readDataFilt(Sof& sof, const String& pname, long size = SofParser::FULL_OBJECT, boolean param = true, boolean nested = false);

      boolean writeDataFilt(Sof& sof, const String& pname) const;

- algorithm and implementation specific computational methods: summation

      boolean computeSum(VectorFloat& output, const VectorFloat& input);

- algorithm and implementation specific computational methods: filter

      boolean computeFilt(VectorFloat& output, const VectorFloat& input, long channel_index);

- scaling methods: common to all algorithms

      boolean scale(const Float& value, long len);

examples:

- This example shows how to compute the energy of input vector in dB using the SUM algorithm:

      // declare an Energy object and an output vector
      //
      Energy egy;
      VectorFloat output;

      // set the input vector
      //
      VectorFloat input(L"0, 1, 2");

      // choose algorithm
      //
      enrgy.setAlgorithm(Energy::SUM);

      // choose implementation
      //
      egy.setImplementation(Energy::DB);

      // compute the energy of input data
      //
      egy.compute(output, input);

- This example shows how to compute the log power of the input vector using the FILTER algorithm:

      // declare an Energy object and an output vector
      //
      Energy egy;
      VectorFloat output;

      // set the input vector
      //

      VectorFloat input(L"0,1,2,3,4")

      // choose the algorithm and implementation
      //
      egy.setAlgorithm(Energy::FILTER);
      egy.setImplementation(Energy::LOG_POWER);

      // set up a filter
      //
      VectorFloat ma_coef(L"1,1,1");
      VectorFloat ar_coef(L"1");
      egy.setFilter(ma_coef, ar_coef);

      // compute the energy of input data
      //
      egy.compute(output, input);

notes:

- The computed energy is stored as the first element in the output vector.
- The FILTER algorithm is restricted to causal linear filters. It was implemented directly instead of using the Filter class because of some complications involving multichannel signals due to the algorithm programming interface.
- Technically, the FILTER algorithm operates in CROSS_FRAME mode, since it operates on data outside the current frame. However, the FILTER algorithm uses its own internal filter memory, and does not need to rely on the apply method's circular buffers to maintain history. Hence, only the FRAME_INTERNAL mode is allowed.
- Similarly, if the FILTER algorithm is selected, and the compute mode is used (which assumes single frame at a time processing), the programmer must manually reset the filter as desired using the init() method.