Mercurial > hg > jvamp
diff org/vamp_plugins/Plugin.java @ 28:f2914a92b553
Docs
author | Chris Cannam |
---|---|
date | Mon, 19 Nov 2012 15:12:44 +0000 |
parents | b568b30c167f |
children | c9515589be7d |
line wrap: on
line diff
--- 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(); }