Chris@0
|
1
|
Chris@0
|
2 package org.vamp_plugins;
|
Chris@0
|
3
|
Chris@2
|
4 import java.util.TreeMap;
|
Chris@2
|
5 import java.util.ArrayList;
|
Chris@2
|
6
|
Chris@28
|
7 /**
|
Chris@28
|
8 * A Java wrapper for a native-code Vamp plugin. Plugins are obtained
|
Chris@28
|
9 * using PluginLoader and must be freed by calling dispose() after use
|
Chris@28
|
10 * (being native code they cannot be garbage collected).
|
Chris@28
|
11 *
|
Chris@28
|
12 * The plugin lifecycle looks roughly like this, from the host's
|
Chris@28
|
13 * perspective:
|
Chris@28
|
14 *
|
Chris@28
|
15 * - Plugin is loaded using PluginLoader
|
Chris@28
|
16 *
|
Chris@28
|
17 * - Host may query the plugin's available outputs with
|
Chris@28
|
18 * getOutputDescriptors(). This will report what outputs exist,
|
Chris@28
|
19 * but their properties (e.g. resolution, value count, extents)
|
Chris@28
|
20 * are not yet fixed
|
Chris@28
|
21 *
|
Chris@28
|
22 * - Host may query and set the plugin's programs and parameters with
|
Chris@28
|
23 * getPrograms(), getParameterDescriptors(), setParameter() etc
|
Chris@28
|
24 *
|
Chris@28
|
25 * - After all parameters are set, host queries the plugin's preferred
|
Chris@28
|
26 * step size, block size, and channel count (which may depend on
|
Chris@28
|
27 * the parameter settings)
|
Chris@28
|
28 *
|
Chris@28
|
29 * - Host initialises plugin by calling initialise(). If it returns
|
Chris@28
|
30 * false, initialise failed -- most likely because the step size,
|
Chris@28
|
31 * block size, or channel count was rejected
|
Chris@28
|
32 *
|
Chris@28
|
33 * - Host may now get final values for the output properties using
|
Chris@28
|
34 * getOutputDescriptors()
|
Chris@28
|
35 *
|
Chris@28
|
36 * - Host calls process() repeatedly to process data. This may return
|
Chris@28
|
37 * some results as it goes along (if the plugin is causal)
|
Chris@28
|
38 *
|
Chris@28
|
39 * - Host calls getRemainingFeatures() exactly once when all input has
|
Chris@28
|
40 * been processed, to obtain any non-causal or leftover features.
|
Chris@28
|
41 *
|
Chris@28
|
42 * - At any point after initialise() has been called, host may call
|
Chris@28
|
43 * reset() to restart processing. Parameter values remain fixed
|
Chris@28
|
44 * across reset() calls.
|
Chris@28
|
45 *
|
Chris@28
|
46 * - When host is finished with plugin, it calls dispose().
|
Chris@28
|
47 *
|
Chris@28
|
48 * The host may not change any parameter or program settings after
|
Chris@28
|
49 * calling initialise(), and may not call initialise() more than once
|
Chris@28
|
50 * on any given plugin.
|
Chris@28
|
51 *
|
Chris@28
|
52 * See the PluginBase and Plugin classes in the C++ Vamp plugin SDK
|
Chris@28
|
53 * for further documentation.
|
Chris@28
|
54 */
|
Chris@0
|
55 public class Plugin
|
Chris@0
|
56 {
|
Chris@0
|
57 private long nativeHandle;
|
Chris@0
|
58 protected Plugin(long handle) { nativeHandle = handle; }
|
Chris@0
|
59
|
Chris@28
|
60 /**
|
Chris@28
|
61 * Dispose of this Plugin. Call this when you have finished using
|
Chris@28
|
62 * it to ensure the native code object is released.
|
Chris@28
|
63 */
|
Chris@20
|
64 public native void dispose();
|
Chris@20
|
65
|
Chris@28
|
66 /**
|
Chris@28
|
67 * Get the Vamp API compatibility level of the plugin.
|
Chris@28
|
68 */
|
Chris@28
|
69 public native int getVampApiVersion();
|
Chris@3
|
70
|
Chris@28
|
71 /**
|
Chris@28
|
72 * Get the computer-usable name of the plugin. This will contain
|
Chris@28
|
73 * only the characters [a-zA-Z0-9_-]. This is the authoritative
|
Chris@28
|
74 * way for a host to identify a plugin within a given library, but
|
Chris@28
|
75 * it is not the primary label shown to the user (that will be the
|
Chris@28
|
76 * name, below).
|
Chris@28
|
77 */
|
Chris@0
|
78 public native String getIdentifier();
|
Chris@28
|
79
|
Chris@28
|
80 /**
|
Chris@28
|
81 * Get a human-readable name or title of the plugin. This is the
|
Chris@28
|
82 * main identifying label shown to the user.
|
Chris@28
|
83 */
|
Chris@0
|
84 public native String getName();
|
Chris@28
|
85
|
Chris@28
|
86 /**
|
Chris@28
|
87 * Get a human-readable description for the plugin, typically
|
Chris@28
|
88 * a line of text that may optionally be displayed in addition
|
Chris@28
|
89 * to the plugin's "name". May be empty if the name has said
|
Chris@28
|
90 * it all already.
|
Chris@28
|
91 */
|
Chris@0
|
92 public native String getDescription();
|
Chris@28
|
93
|
Chris@28
|
94 /**
|
Chris@28
|
95 * Get the name of the author or vendor of the plugin in
|
Chris@28
|
96 * human-readable form. This should be short enough to be used to
|
Chris@28
|
97 * label plugins from the same source in a tree or menu if
|
Chris@28
|
98 * appropriate.
|
Chris@28
|
99 */
|
Chris@3
|
100 public native String getMaker();
|
Chris@28
|
101
|
Chris@28
|
102 /**
|
Chris@28
|
103 * Get the copyright statement or licensing summary for the
|
Chris@28
|
104 * plugin.
|
Chris@28
|
105 */
|
Chris@3
|
106 public native String getCopyright();
|
Chris@28
|
107
|
Chris@28
|
108 /**
|
Chris@28
|
109 * Get the version number of the plugin.
|
Chris@28
|
110 */
|
Chris@0
|
111 public native int getPluginVersion();
|
Chris@2
|
112
|
Chris@28
|
113 /**
|
Chris@28
|
114 * Get the controllable parameters of this plugin.
|
Chris@28
|
115 */
|
Chris@3
|
116 public native ParameterDescriptor[] getParameterDescriptors();
|
Chris@28
|
117
|
Chris@28
|
118 /**
|
Chris@28
|
119 * Get the value of a named parameter. The argument is the identifier
|
Chris@28
|
120 * field from that parameter's descriptor.
|
Chris@28
|
121 */
|
Chris@3
|
122 public native float getParameter(String identifier);
|
Chris@28
|
123
|
Chris@28
|
124 /**
|
Chris@28
|
125 * Set a named parameter. The first argument is the identifier field
|
Chris@28
|
126 * from that parameter's descriptor.
|
Chris@28
|
127 */
|
Chris@3
|
128 public native void setParameter(String identifier, float value);
|
Chris@3
|
129
|
Chris@28
|
130 /**
|
Chris@28
|
131 * Get the program settings available in this plugin. A program
|
Chris@28
|
132 * is a named shorthand for a set of parameter values; changing
|
Chris@28
|
133 * the program may cause the plugin to alter the values of its
|
Chris@28
|
134 * published parameters (and/or non-public internal processing
|
Chris@28
|
135 * parameters). The host should re-read the plugin's parameter
|
Chris@28
|
136 * values after setting a new program.
|
Chris@28
|
137 *
|
Chris@28
|
138 * The programs must have unique names.
|
Chris@28
|
139 */
|
Chris@3
|
140 public native String[] getPrograms();
|
Chris@28
|
141
|
Chris@28
|
142 /**
|
Chris@28
|
143 * Get the current program (if any).
|
Chris@28
|
144 */
|
Chris@3
|
145 public native String getCurrentProgram();
|
Chris@28
|
146
|
Chris@28
|
147 /**
|
Chris@28
|
148 * Select a program. (If the given program name is not one of the
|
Chris@28
|
149 * available programs, do nothing.)
|
Chris@28
|
150 */
|
Chris@3
|
151 public native void selectProgram(String program);
|
Chris@3
|
152
|
Chris@28
|
153 /**
|
Chris@28
|
154 * Initialise a plugin to prepare it for use with the given number
|
Chris@28
|
155 * of input channels, step size (window increment, in sample
|
Chris@28
|
156 * frames) and block size (window size, in sample frames).
|
Chris@28
|
157 *
|
Chris@28
|
158 * The input sample rate should have been already specified when
|
Chris@28
|
159 * loading the plugin.
|
Chris@28
|
160 *
|
Chris@28
|
161 * Return true for successful initialisation, false if the number
|
Chris@28
|
162 * of input channels, step size and/or block size cannot be
|
Chris@28
|
163 * supported.
|
Chris@28
|
164 */
|
Chris@2
|
165 public native boolean initialise(int inputChannels,
|
Chris@2
|
166 int stepSize,
|
Chris@2
|
167 int blockSize);
|
Chris@2
|
168
|
Chris@28
|
169 /**
|
Chris@28
|
170 * Reset the plugin after use, to prepare it for another clean
|
Chris@28
|
171 * run.
|
Chris@28
|
172 */
|
Chris@2
|
173 public native void reset();
|
Chris@2
|
174
|
Chris@25
|
175 public static enum InputDomain { TIME_DOMAIN, FREQUENCY_DOMAIN };
|
Chris@28
|
176
|
Chris@28
|
177 /**
|
Chris@28
|
178 * Get the plugin's required input domain.
|
Chris@28
|
179 *
|
Chris@28
|
180 * If this is TimeDomain, the samples provided to the process()
|
Chris@28
|
181 * function (below) must be in the time domain, as for a
|
Chris@28
|
182 * traditional audio processing plugin.
|
Chris@28
|
183 *
|
Chris@28
|
184 * If this is FrequencyDomain, the host must carry out a windowed
|
Chris@28
|
185 * FFT of size equal to the negotiated block size on the data
|
Chris@28
|
186 * before passing the frequency bin data in to process(). The
|
Chris@28
|
187 * input data for the FFT will be rotated so as to place the
|
Chris@28
|
188 * origin in the centre of the block. The plugin does not get to
|
Chris@28
|
189 * choose the window type -- the host will either let the user do
|
Chris@28
|
190 * so, or will use a Hanning window.
|
Chris@28
|
191 */
|
Chris@2
|
192 public native InputDomain getInputDomain();
|
Chris@2
|
193
|
Chris@28
|
194 /**
|
Chris@28
|
195 * Get the preferred block size (window size -- the number of
|
Chris@28
|
196 * sample frames passed in each block to the process() function).
|
Chris@28
|
197 * This should be called before initialise().
|
Chris@28
|
198 *
|
Chris@28
|
199 * A plugin that can handle any block size may return 0. The
|
Chris@28
|
200 * final block size will be set in the initialise() call.
|
Chris@28
|
201 */
|
Chris@2
|
202 public native int getPreferredBlockSize();
|
Chris@28
|
203
|
Chris@28
|
204 /**
|
Chris@28
|
205 * Get the preferred step size (window increment -- the distance
|
Chris@28
|
206 * in sample frames between the start frames of consecutive blocks
|
Chris@28
|
207 * passed to the process() function) for the plugin. This should
|
Chris@28
|
208 * be called before initialise().
|
Chris@28
|
209 *
|
Chris@28
|
210 * A plugin may return 0 if it has no particular interest in the
|
Chris@28
|
211 * step size. In this case, the host should make the step size
|
Chris@28
|
212 * equal to the block size if the plugin is accepting input in the
|
Chris@28
|
213 * time domain. If the plugin is accepting input in the frequency
|
Chris@28
|
214 * domain, the host may use any step size. The final step size
|
Chris@28
|
215 * will be set in the initialise() call.
|
Chris@28
|
216 */
|
Chris@2
|
217 public native int getPreferredStepSize();
|
Chris@28
|
218
|
Chris@28
|
219 /**
|
Chris@28
|
220 * Get the minimum supported number of input channels.
|
Chris@28
|
221 */
|
Chris@2
|
222 public native int getMinChannelCount();
|
Chris@28
|
223
|
Chris@28
|
224 /**
|
Chris@28
|
225 * Get the maximum supported number of input channels.
|
Chris@28
|
226 */
|
Chris@2
|
227 public native int getMaxChannelCount();
|
Chris@2
|
228
|
Chris@28
|
229 /**
|
Chris@28
|
230 * Get the outputs of this plugin. An output's index in this list
|
Chris@28
|
231 * is used as its numeric index when looking it up in the
|
Chris@28
|
232 * FeatureSet returned from the process() call.
|
Chris@28
|
233 */
|
Chris@2
|
234 public native OutputDescriptor[] getOutputDescriptors();
|
Chris@2
|
235
|
Chris@28
|
236 /**
|
Chris@28
|
237 * Process a single block of input data.
|
Chris@28
|
238 *
|
Chris@28
|
239 * If the plugin's inputDomain is TimeDomain, inputBuffers must
|
Chris@28
|
240 * contain one array of floats per input channel, and each of
|
Chris@28
|
241 * these arrays will contain blockSize consecutive audio samples
|
Chris@28
|
242 * (the host will zero-pad as necessary). The timestamp in this
|
Chris@28
|
243 * case will be the real time in seconds of the start of the
|
Chris@28
|
244 * supplied block of samples.
|
Chris@28
|
245 *
|
Chris@28
|
246 * If the plugin's inputDomain is FrequencyDomain, inputBuffers
|
Chris@28
|
247 * must contain one array of floats per input channel, and each of
|
Chris@28
|
248 * these arrays will contain blockSize/2+1 consecutive pairs of
|
Chris@28
|
249 * real and imaginary component floats corresponding to bins
|
Chris@28
|
250 * 0..(blockSize/2) of the FFT output. That is, bin 0 (the first
|
Chris@28
|
251 * pair of floats) contains the DC output, up to bin blockSize/2
|
Chris@28
|
252 * which contains the Nyquist-frequency output. There will
|
Chris@28
|
253 * therefore be blockSize+2 floats per channel in total. The
|
Chris@28
|
254 * timestamp will be the real time in seconds of the centre of the
|
Chris@28
|
255 * FFT input window (i.e. the very first block passed to process
|
Chris@28
|
256 * might contain the FFT of half a block of zero samples and the
|
Chris@28
|
257 * first half-block of the actual data, with a timestamp of zero).
|
Chris@28
|
258 *
|
Chris@28
|
259 * Return any features that have become available after this
|
Chris@28
|
260 * process call. (These do not necessarily have to fall within
|
Chris@28
|
261 * the process block, except for OneSamplePerStep outputs.)
|
Chris@28
|
262 */
|
Chris@22
|
263 public TreeMap<Integer, ArrayList<Feature>>
|
Chris@22
|
264 process(float[][] inputBuffers,
|
Chris@22
|
265 RealTime timestamp) {
|
Chris@24
|
266 return process(inputBuffers, 0, timestamp);
|
Chris@22
|
267 }
|
Chris@22
|
268
|
Chris@28
|
269 /**
|
Chris@28
|
270 * As process() above, but taking input data starting at the given
|
Chris@28
|
271 * offset from within each of the channel arrays. Provided to
|
Chris@28
|
272 * avoid potentially having to extract a set of sub-arrays from
|
Chris@28
|
273 * longer arrays (fiddly in Java).
|
Chris@28
|
274 */
|
Chris@2
|
275 public native TreeMap<Integer, ArrayList<Feature>>
|
Chris@2
|
276 process(float[][] inputBuffers,
|
Chris@24
|
277 int offset,
|
Chris@2
|
278 RealTime timestamp);
|
Chris@2
|
279
|
Chris@28
|
280 /**
|
Chris@28
|
281 * After all blocks have been processed, calculate and return any
|
Chris@28
|
282 * remaining features derived from the complete input.
|
Chris@28
|
283 */
|
Chris@2
|
284 public native TreeMap<Integer, ArrayList<Feature>>
|
Chris@2
|
285 getRemainingFeatures();
|
Chris@0
|
286 }
|
Chris@0
|
287
|