package org.vocvark;
import org.vocvark.Aggregators.Aggregator;
import org.vocvark.Aggregators.AggregatorContainer;
import org.vocvark.AudioFeatures.FeatureExtractor;
import org.vocvark.DataTypes.ExtractionResult;
import org.vocvark.DataTypes.RecordingInfo;
import org.vocvark.DataTypes.Settings;
import org.vocvark.XMLParsers.XMLDocumentParser;
import org.vocvark.jAudioTools.FeaturesExtractionProcessor;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Date: 12.05.12
*
* @author Vladimir Kravtsov
*/
public final class FeaturesExtraction {
private HashMap<String, Aggregator> aggregatorMap;
private List<FeatureExtractor> features;
private Boolean[] defaults;
private RecordingInfo[] recordings;
private Map<String, Boolean> activatedFeatureMap;
private Map<String, String[]> attributes;
private List<Aggregator> aggregators;
private AggregatorContainer aggregatorContainer;
public List<ExtractionResult> extract(File[] files) throws Exception {
return extract(files, null);
}
public List<ExtractionResult> extract(File[] files, Settings settings) throws Exception {
initRecordings(files);
parseFeatureExtractorsList();
initAggregatorContainer();
applyAttributes();
if (recordings == null) {
throw new Exception("No recordings available to extract features from.");
}
// Prepare to extract features
FeaturesExtractionProcessor processor = new FeaturesExtractionProcessor(
settings != null ? settings : new Settings(),
features,
defaults,
new Cancel(),
aggregatorContainer
);
List<ExtractionResult> result = new ArrayList<ExtractionResult>(recordings.length);
for (RecordingInfo recording : recordings) {
result.add(processor.extractFeatures(recording, null));
}
return result;
}
/**
* Sets the recordings that this batch will load and execute.
*
* @param files recordings which are to be scheduled for porcessing.
* @throws Exception
*/
public void initRecordings(File[] files) throws Exception {
recordings = new RecordingInfo[files.length];
// Go through the files one by one
for (int i = 0; i < files.length; i++) {
// Verify that the file exists
if (files[i].exists()) {
try {
// Generate a RecordingInfo object for the loaded file
recordings[i] = new RecordingInfo(files[i].getName(), files[i].getPath(), null, false);
} catch (Exception e) {
recordings = null;
throw e;
}
} else {
recordings = null;
throw new Exception("The selected file " + files[i].getName() + " does not exist.");
}
}
}
/**
* Apply the stored attributes against the current feature list.
*
* @throws Exception
*/
private void applyAttributes() throws Exception {
if (activatedFeatureMap == null && attributes == null) {
return;
}
for (int i = 0; i < features.size(); ++i) {
String name = features.get(i).getFeatureDefinition().name;
if (attributes.containsKey(name)) {
defaults[i] = activatedFeatureMap.get(name);
String[] tmp = attributes.get(name);
for (int j = 0; j < tmp.length; ++j) {
features.get(i).setElement(j, tmp[j]);
}
}
}
}
private void initAggregatorContainer() throws Exception {
if(aggregators == null || aggregators.isEmpty()) {
aggregators = new ArrayList<Aggregator>();
aggregators.add(new org.vocvark.Aggregators.Mean());
aggregators.add(new org.vocvark.Aggregators.StandardDeviation());
org.vocvark.Aggregators.AreaMoments areaMoments = new org.vocvark.Aggregators.AreaMoments();
areaMoments.setParameters(new String[]{"Area Method of Moments of MFCCs"}, new String[]{""});
aggregators.add(areaMoments);
}
aggregatorContainer = new AggregatorContainer();
aggregatorContainer.addAggregatorList(aggregators);
}
@SuppressWarnings("unchecked")
private void parseFeatureExtractorsList() {
LinkedList<FeatureExtractor> featureExtractors = new LinkedList<FeatureExtractor>();
aggregatorMap = new java.util.HashMap<String, Aggregator>();
URL featuresXmlUrl = getClass().getClassLoader().getResource("features.xml");
String featureXMLLocation = "features.xml";//featuresXmlUrl.getPath();
LinkedList<Boolean> def = new LinkedList<Boolean>();
try {
Object[] lists = (Object[]) XMLDocumentParser.parseXMLDocument(featureXMLLocation, "feature_list");
featureExtractors = (LinkedList<FeatureExtractor>) lists[0];
def = (LinkedList<Boolean>) lists[1];
for (Aggregator aggregator : (LinkedList<Aggregator>) lists[2]) {
aggregatorMap.put(aggregator.getAggregatorDefinition().name, aggregator);
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
this.features = featureExtractors;
def.toArray(this.defaults = new Boolean[def.size()]);
}
public Map<String, Boolean> getActivatedFeatureMap() {
return activatedFeatureMap;
}
public void setActivatedFeatureMap(Map<String, Boolean> activatedFeatureMap) {
this.activatedFeatureMap = activatedFeatureMap;
}
public Map<String, String[]> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, String[]> attributes) {
this.attributes = attributes;
}
public RecordingInfo[] getRecordings() {
return recordings;
}
public void setRecordings(RecordingInfo[] recordings) {
this.recordings = recordings;
}
}