changeset 28:f2914a92b553

Docs
author Chris Cannam
date Mon, 19 Nov 2012 15:12:44 +0000
parents 59b4150c69cb
children 7d1118b3860d
files org/vamp_plugins/Feature.java org/vamp_plugins/OutputDescriptor.java org/vamp_plugins/ParameterDescriptor.java org/vamp_plugins/Plugin.java
diffstat 4 files changed, 423 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/org/vamp_plugins/Feature.java	Fri Nov 16 08:01:01 2012 +0000
+++ b/org/vamp_plugins/Feature.java	Mon Nov 19 15:12:44 2012 +0000
@@ -1,13 +1,54 @@
 
 package org.vamp_plugins;
 
+/**
+ * Feature contains a single result returned from Plugin.process() or
+ * Plugin.getRemainingFeatures().
+ */
 public class Feature {
+    /**
+     * True if an output feature has its own timestamp.  This is
+     * mandatory if the output has VariableSampleRate, optional if
+     * the output has FixedSampleRate, and unused if the output
+     * has OneSamplePerStep.
+     */
     public boolean hasTimestamp;
+
+    /**
+     * Timestamp of the output feature.  This is mandatory if the
+     * output has VariableSampleRate or if the output has
+     * FixedSampleRate and hasTimestamp is true, and unused
+     * otherwise.
+     */
     public RealTime timestamp;
+
+    /**
+     * True if an output feature has a specified duration.  This
+     * is optional if the output has VariableSampleRate or
+     * FixedSampleRate, and and unused if the output has
+     * OneSamplePerStep.
+     */
     public boolean hasDuration;
+
+    /**
+     * Duration of the output feature.  This is mandatory if the
+     * output has VariableSampleRate or FixedSampleRate and
+     * hasDuration is true, and unused otherwise.
+     */
     public RealTime duration;
+	
+    /**
+     * Results for a single sample of this feature.  If the output
+     * hasFixedBinCount, there must be the same number of values
+     * as the output's binCount count.
+     */
     public float[] values;
+
+    /**
+     * Label for the sample of this feature.
+     */
     public String label;
+
     Feature() {
 	hasTimestamp = false; hasDuration = false;
     }
--- a/org/vamp_plugins/OutputDescriptor.java	Fri Nov 16 08:01:01 2012 +0000
+++ b/org/vamp_plugins/OutputDescriptor.java	Mon Nov 19 15:12:44 2012 +0000
@@ -1,24 +1,118 @@
 
 package org.vamp_plugins;
 
+/**
+ * OutputDescriptor describes the properties of an output of a Vamp
+ * plugin. Returned by e.g. Plugin.getOutputDescriptors().
+ */
 public class OutputDescriptor {
+
+    /**
+     * The name of the output, in computer-usable form.  Will contain
+     * the characters [a-zA-Z0-9_-] only.
+     */
     public String identifier;
+
+    /**
+     * The human-readable name of the output.
+     */
     public String name;
+
+    /**
+     * A human-readable short text describing the output.  May be
+     * empty if the name has said it all already.
+     */
     public String description;
+
+    /**
+     * The unit of the output, in human-readable form.
+     */
     public String unit;
+
+    /**
+     * True if the output has the same number of values per sample
+     * for every output sample.
+     */
     public boolean hasFixedBinCount;
+
+    /**
+     * The number of values per result of the output.  Undefined
+     * if hasFixedBinCount is false.  If this is zero, the output
+     * is point data (i.e. only the time of each output is of
+     * interest, the value list will be empty).
+     */
     public int binCount;
+
+    /**
+     * The (human-readable) names of each of the bins, if
+     * appropriate.  This is always optional.
+     */
     public String[] binNames;
+
+    /**
+     * True if the results in each output bin fall within a fixed
+     * numeric range (minimum and maximum values).  Undefined if
+     * binCount is zero.
+     */
     public boolean hasKnownExtents;
+
+    /**
+     * Minimum value of the results in the output.  Undefined if
+     * hasKnownExtents is false or binCount is zero.
+     */
     public float minValue;
+
+    /**
+     * Maximum value of the results in the output.  Undefined if
+     * hasKnownExtents is false or binCount is zero.
+     */
     public float maxValue;
+
+    /**
+     * True if the output values are quantized to a particular
+     * resolution.  Undefined if binCount is zero.
+     */
     public boolean isQuantized;
+
+    /**
+     * Quantization resolution of the output values (e.g. 1.0 if
+     * they are all integers).  Undefined if isQuantized is false
+     * or binCount is zero.
+     */
     public float quantizeStep;
+
     public static enum SampleType {
-	OneSamplePerStep, FixedSampleRate, VariableSampleRate
+	/// Results from each process() align with that call's block start
+	OneSamplePerStep,
+
+	/// Results are evenly spaced in time (sampleRate specified below)
+	FixedSampleRate,
+
+	/// Results are unevenly spaced and have individual timestamps
+	VariableSampleRate
     };
+
+    /**
+     * Positioning in time of the output results.
+     */
     public SampleType sampleType;
+
+    /**
+     * Sample rate of the output results, as samples per second.
+     * Undefined if sampleType is OneSamplePerStep.
+     *
+     * If sampleType is VariableSampleRate and this value is
+     * non-zero, then it may be used to calculate a resolution for
+     * the output (i.e. the "duration" of each sample, in time,
+     * will be 1/sampleRate seconds).  It's recommended to set
+     * this to zero if that behaviour is not desired.
+     */
     public float sampleRate;
+
+    /**
+     * True if the returned results for this output are known to
+     * have a duration field.
+     */
     public boolean hasDuration;
 
     OutputDescriptor() {
--- a/org/vamp_plugins/ParameterDescriptor.java	Fri Nov 16 08:01:01 2012 +0000
+++ b/org/vamp_plugins/ParameterDescriptor.java	Mon Nov 19 15:12:44 2012 +0000
@@ -1,16 +1,76 @@
 
 package org.vamp_plugins;
 
+/**
+ * ParameterDescriptor describes the properties of a configurable
+ * parameter of a Plugin.
+ */
 public class ParameterDescriptor {
+
+    /**
+     * The name of the parameter, in computer-usable form.  Will
+     * contain only the characters [a-zA-Z0-9_-].
+     */
     public String identifier;
+
+    /**
+     * The human-readable name of the parameter.
+     */
     public String name;
+
+    /**
+     * A human-readable short text describing the parameter.  May be
+     * empty if the name has said it all already.
+     */
     public String description;
+
+    /**
+     * The unit of the parameter, in human-readable form.
+     */
     public String unit;
+
+    /**
+     * The minimum value of the parameter.
+     */
     public float minValue;
+
+    /**
+     * The maximum value of the parameter.
+     */
     public float maxValue;
+
+    /**
+     * The default value of the parameter.  The plugin should
+     * ensure that parameters have this value on initialisation
+     * (i.e. the host is not required to explicitly set parameters
+     * if it wants to use their default values).
+     */
     public float defaultValue;
+	
+    /**
+     * True if the parameter values are quantized to a particular
+     * resolution.
+     */
     public boolean isQuantized;
+
+    /**
+     * Quantization resolution of the parameter values (e.g. 1.0
+     * if they are all integers).  Undefined if isQuantized is
+     * false.
+     */
     public float quantizeStep;
+
+    /**
+     * Names for the quantized values.  If isQuantized is true,
+     * this may either be empty or contain one string for each of
+     * the quantize steps from minValue up to maxValue inclusive.
+     * Undefined if isQuantized is false.
+     *
+     * If these names are provided, they should be shown to the
+     * user in preference to the values themselves.  The user may
+     * never see the actual numeric values unless they are also
+     * encoded in the names.
+     */
     public String[] valueNames;
 	
     ParameterDescriptor() {
--- a/org/vamp_plugins/Plugin.java	Fri Nov 16 08:01:01 2012 +0000
+++ b/org/vamp_plugins/Plugin.java	Mon Nov 19 15:12:44 2012 +0000
@@ -4,65 +4,283 @@
 import java.util.TreeMap;
 import java.util.ArrayList;
 
+/**
+ * A Java wrapper for a native-code Vamp plugin. Plugins are obtained
+ * using PluginLoader and must be freed by calling dispose() after use
+ * (being native code they cannot be garbage collected).
+ *
+ * The plugin lifecycle looks roughly like this, from the host's
+ * perspective:
+ *
+ * - Plugin is loaded using PluginLoader
+ *
+ * - Host may query the plugin's available outputs with
+ *    getOutputDescriptors(). This will report what outputs exist,
+ *    but their properties (e.g. resolution, value count, extents)
+ *    are not yet fixed
+ *
+ * - Host may query and set the plugin's programs and parameters with
+ *    getPrograms(), getParameterDescriptors(), setParameter() etc
+ *
+ * - After all parameters are set, host queries the plugin's preferred
+ *    step size, block size, and channel count (which may depend on
+ *    the parameter settings)
+ *
+ * - Host initialises plugin by calling initialise(). If it returns
+ *    false, initialise failed -- most likely because the step size,
+ *    block size, or channel count was rejected
+ *
+ * - Host may now get final values for the output properties using
+ *    getOutputDescriptors()
+ *
+ * - Host calls process() repeatedly to process data. This may return
+ *    some results as it goes along (if the plugin is causal)
+ *
+ * - Host calls getRemainingFeatures() exactly once when all input has
+ *    been processed, to obtain any non-causal or leftover features.
+ *
+ * - At any point after initialise() has been called, host may call
+ *    reset() to restart processing. Parameter values remain fixed
+ *    across reset() calls.
+ *
+ * - When host is finished with plugin, it calls dispose().
+ *
+ * The host may not change any parameter or program settings after
+ * calling initialise(), and may not call initialise() more than once
+ * on any given plugin.
+ *
+ * See the PluginBase and Plugin classes in the C++ Vamp plugin SDK
+ * for further documentation.
+ */
 public class Plugin
 {
     private long nativeHandle;
     protected Plugin(long handle) { nativeHandle = handle; }
 
+    /**
+     * Dispose of this Plugin. Call this when you have finished using
+     * it to ensure the native code object is released.
+     */
     public native void dispose();
 
-    // PluginBase methods
+    /**
+     * Get the Vamp API compatibility level of the plugin.
+     */
+    public native int getVampApiVersion();
 
-    public native int getVampApiVersion();
+    /**
+     * Get the computer-usable name of the plugin.  This will contain
+     * only the characters [a-zA-Z0-9_-].  This is the authoritative
+     * way for a host to identify a plugin within a given library, but
+     * it is not the primary label shown to the user (that will be the
+     * name, below).
+     */
     public native String getIdentifier();
+
+    /**
+     * Get a human-readable name or title of the plugin.  This is the
+     * main identifying label shown to the user.
+     */
     public native String getName();
+
+    /**
+     * Get a human-readable description for the plugin, typically
+     * a line of text that may optionally be displayed in addition
+     * to the plugin's "name".  May be empty if the name has said
+     * it all already.
+     */
     public native String getDescription();
+    
+    /**
+     * Get the name of the author or vendor of the plugin in
+     * human-readable form. This should be short enough to be used to
+     * label plugins from the same source in a tree or menu if
+     * appropriate.
+     */
     public native String getMaker();
+
+    /**
+     * Get the copyright statement or licensing summary for the
+     * plugin.
+     */
     public native String getCopyright();
+
+    /**
+     * Get the version number of the plugin.
+     */
     public native int getPluginVersion();
 
+    /**
+     * Get the controllable parameters of this plugin.
+     */
     public native ParameterDescriptor[] getParameterDescriptors();
+
+    /**
+     * Get the value of a named parameter.  The argument is the identifier
+     * field from that parameter's descriptor.
+     */
     public native float getParameter(String identifier);
+
+    /**
+     * Set a named parameter.  The first argument is the identifier field
+     * from that parameter's descriptor.
+     */
     public native void setParameter(String identifier, float value);
 
+    /**
+     * Get the program settings available in this plugin.  A program
+     * is a named shorthand for a set of parameter values; changing
+     * the program may cause the plugin to alter the values of its
+     * published parameters (and/or non-public internal processing
+     * parameters).  The host should re-read the plugin's parameter
+     * values after setting a new program.
+     *
+     * The programs must have unique names.
+     */
     public native String[] getPrograms();
+
+    /**
+     * Get the current program (if any).
+     */
     public native String getCurrentProgram();
+
+    /**
+     * Select a program.  (If the given program name is not one of the
+     * available programs, do nothing.)
+     */
     public native void selectProgram(String program);
 
-    // Plugin methods
-
+    /**
+     * Initialise a plugin to prepare it for use with the given number
+     * of input channels, step size (window increment, in sample
+     * frames) and block size (window size, in sample frames).
+     *
+     * The input sample rate should have been already specified when
+     * loading the plugin.
+     * 
+     * Return true for successful initialisation, false if the number
+     * of input channels, step size and/or block size cannot be
+     * supported.
+     */
     public native boolean initialise(int inputChannels,
 				     int stepSize,
 				     int blockSize);
 
+    /**
+     * Reset the plugin after use, to prepare it for another clean
+     * run.
+     */
     public native void reset();
     
     public static enum InputDomain { TIME_DOMAIN, FREQUENCY_DOMAIN };
+    
+    /**
+     * Get the plugin's required input domain.
+     *
+     * If this is TimeDomain, the samples provided to the process()
+     * function (below) must be in the time domain, as for a
+     * traditional audio processing plugin.
+     *
+     * If this is FrequencyDomain, the host must carry out a windowed
+     * FFT of size equal to the negotiated block size on the data
+     * before passing the frequency bin data in to process().  The
+     * input data for the FFT will be rotated so as to place the
+     * origin in the centre of the block.  The plugin does not get to
+     * choose the window type -- the host will either let the user do
+     * so, or will use a Hanning window.
+     */
     public native InputDomain getInputDomain();
     
+    /**
+     * Get the preferred block size (window size -- the number of
+     * sample frames passed in each block to the process() function).
+     * This should be called before initialise().
+     *
+     * A plugin that can handle any block size may return 0.  The
+     * final block size will be set in the initialise() call.
+     */
     public native int getPreferredBlockSize();
+
+    /**
+     * Get the preferred step size (window increment -- the distance
+     * in sample frames between the start frames of consecutive blocks
+     * passed to the process() function) for the plugin.  This should
+     * be called before initialise().
+     *
+     * A plugin may return 0 if it has no particular interest in the
+     * step size.  In this case, the host should make the step size
+     * equal to the block size if the plugin is accepting input in the
+     * time domain.  If the plugin is accepting input in the frequency
+     * domain, the host may use any step size.  The final step size
+     * will be set in the initialise() call.
+     */
     public native int getPreferredStepSize();
+
+    /**
+     * Get the minimum supported number of input channels.
+     */
     public native int getMinChannelCount();
+
+    /**
+     * Get the maximum supported number of input channels.
+     */
     public native int getMaxChannelCount();
 
+    /**
+     * Get the outputs of this plugin.  An output's index in this list
+     * is used as its numeric index when looking it up in the
+     * FeatureSet returned from the process() call.
+     */
     public native OutputDescriptor[] getOutputDescriptors();
 
-// "Pseudo-typedef antipattern - don't do this": http://www.ibm.com/developerworks/java/library/j-jtp02216/index.html
-// (I would like to!)
-//    public class FeatureList extends ArrayList<Feature>;
-//    public class FeatureSet extends TreeMap<Integer, FeatureList>;
-
+    /**
+     * Process a single block of input data.
+     * 
+     * If the plugin's inputDomain is TimeDomain, inputBuffers must
+     * contain one array of floats per input channel, and each of
+     * these arrays will contain blockSize consecutive audio samples
+     * (the host will zero-pad as necessary).  The timestamp in this
+     * case will be the real time in seconds of the start of the
+     * supplied block of samples.
+     *
+     * If the plugin's inputDomain is FrequencyDomain, inputBuffers
+     * must contain one array of floats per input channel, and each of
+     * these arrays will contain blockSize/2+1 consecutive pairs of
+     * real and imaginary component floats corresponding to bins
+     * 0..(blockSize/2) of the FFT output.  That is, bin 0 (the first
+     * pair of floats) contains the DC output, up to bin blockSize/2
+     * which contains the Nyquist-frequency output.  There will
+     * therefore be blockSize+2 floats per channel in total.  The
+     * timestamp will be the real time in seconds of the centre of the
+     * FFT input window (i.e. the very first block passed to process
+     * might contain the FFT of half a block of zero samples and the
+     * first half-block of the actual data, with a timestamp of zero).
+     *
+     * Return any features that have become available after this
+     * process call.  (These do not necessarily have to fall within
+     * the process block, except for OneSamplePerStep outputs.)
+     */
     public TreeMap<Integer, ArrayList<Feature>>
 	process(float[][] inputBuffers,
 		RealTime timestamp) {
 	return process(inputBuffers, 0, timestamp);
     }
 
+    /**
+     * As process() above, but taking input data starting at the given
+     * offset from within each of the channel arrays. Provided to
+     * avoid potentially having to extract a set of sub-arrays from
+     * longer arrays (fiddly in Java).
+     */
     public native TreeMap<Integer, ArrayList<Feature>>
 	process(float[][] inputBuffers,
 		int offset,
 		RealTime timestamp);
 
+    /**
+     * After all blocks have been processed, calculate and return any
+     * remaining features derived from the complete input.
+     */
     public native TreeMap<Integer, ArrayList<Feature>>
 	getRemainingFeatures();
 }