/*
* @(#)FractionOfLowEnergyWindows.java 1.0 April 5, 2005.
*
* McGill Univarsity
*/
package org.vocvark.AudioFeatures;
import org.vocvark.DataTypes.FeatureDefinition;
/**
* A feature extractor that extracts the Fraction Of Low Energy Windows from
* window to window. This is a good measure of how much of a signal is quiet
* relative to the rest of a signal. <pThis is calculated by taking the mean of
* the RMS of the last 100 windows and finding what fraction of these 100
* windows are below the mean.
* <p/>
* No extracted feature values are stored in objects of this class.
* <p/>
* Daniel McEnnis 05-07-05 added number_of_windows as editable property. Added
* getElement, setElement, and clone
* <p/>
* Daniel McEnnis 05-08-05 added setWindow to permit this feature to be edited
* by GlobalWindow frame.
*
* @author Cory McKay
*/
public class FractionOfLowEnergyWindows extends FeatureExtractorBaseImpl {
private int number_windows = 100;
/* CONSTRUCTOR ************************************************************* */
/**
* Basic constructor that sets the definition and dependencies (and their
* offsets) of this feature.
*/
public FractionOfLowEnergyWindows() {
String name = "Fraction Of Low Energy Windows";
String description = "The fraction of the last 100 windows that has an "
+ "RMS less than the mean RMS in the last 100 windows. "
+ "This can indicate how much of a signal is quiet "
+ "relative to the rest of the signal.";
boolean is_sequential = true;
int dimensions = 1;
definition = new FeatureDefinition(name, description, is_sequential,
dimensions);
dependencies = new String[number_windows];
for (int i = 0; i < dependencies.length; i++)
dependencies[i] = "Root Mean Square";
offsets = new int[number_windows];
for (int i = 0; i < offsets.length; i++)
offsets[i] = 0 - i;
}
/* PUBLIC METHODS ********************************************************* */
/**
* Extracts this feature from the given samples at the given sampling rate
* and given the other feature values.
* <p/>
* In the case of this feature the sampling_rate is ignored.
*
* @param samples The samples to extract the feature from.
* @param sampling_rate The sampling rate that the samples are encoded with.
* @param other_feature_values The values of other features that are needed to calculate this
* value. The order and offsets of these features must be the
* same as those returned by this class's getDependencies and
* getDependencyOffsets methods respectively. The first indice
* indicates the feature/window and the second indicates the
* value.
* @return The extracted feature value(s).
* @throws Exception Throws an informative exception if the feature cannot be
* calculated.
*/
public double[] extractFeature(double[] samples, double sampling_rate,
double[][] other_feature_values) throws Exception {
double average = 0.0;
for (int i = 0; i < other_feature_values.length; i++)
average += other_feature_values[i][0];
average = average / ((double) other_feature_values.length);
int count = 0;
for (int i = 0; i < other_feature_values.length; i++)
if (other_feature_values[i][0] < average)
count++;
double[] result = new double[1];
result[0] = ((double) count) / ((double) other_feature_values.length);
return result;
}
/**
* Function that must be overridden to allow this feature to be set globally
* by GlobalChange frame.
*
* @param n the number of windows of offset to be used in calculating this
* feature
*/
public void setWindow(int n) throws Exception {
if (n < 2) {
throw new Exception(
"Fraction Of Low Energy Frames's window length must be 2 or greater");
} else {
number_windows = n;
dependencies = new String[number_windows];
offsets = new int[number_windows];
for (int i = 0; i < number_windows; ++i) {
dependencies[i] = "Root Mean Square";
offsets[i] = 0 - i;
}
}
}
/**
* Function permitting an unintelligent outside function (ie. EditFeatures
* frame) to get the default values used to populate the table's entries.
* The correct index values are inferred from definition.attribute value.
*
* @param index which of AreaMoment's attributes should be edited.
*/
public String getElement(int index) throws Exception {
if (index != 0) {
throw new Exception("INTERNAL ERROR: invalid index " + index
+ " sent to FractionOfLowEnergyFrames:getElement");
} else {
return Integer.toString(number_windows);
}
}
/**
* Function permitting an unintelligent outside function (ie. EditFeatures
* frame) to set the default values used to popylate the table's entries.
* Like getElement, the correct index values are inferred from the
* definition.attributes value.
*
* @param index attribute to be set
* @param value new value of the attribute
*/
public void setElement(int index, String value) throws Exception {
if (index != 0) {
throw new Exception("INTERNAL ERROR: invalid index " + index
+ " sent to FractionOfLowEnergyFrames:setElement");
} else {
try {
int type = Integer.parseInt(value);
setWindow(type);
} catch (Exception e) {
throw new Exception(
"Length of Fraction Of Low Energy Frames's window must be an integer");
}
}
}
/**
* Create an identical copy of this feature. This permits FeatureExtractor
* to use the prototype pattern to create new composite features using
* metafeatures.
*/
public Object clone() {
FractionOfLowEnergyWindows ret = new FractionOfLowEnergyWindows();
ret.number_windows = number_windows;
return ret;
}
}