Revision 0:f89128a316e7
| .hgignore | ||
|---|---|---|
| 1 |
syntax: glob |
|
| 2 |
*.o |
|
| 3 |
*~ |
|
| 4 |
*.so |
|
| 5 |
*.dll |
|
| 6 |
*.exe |
|
| 7 |
vamp-plugin-tester |
|
| .hgsub | ||
|---|---|---|
| 1 |
vamp-plugin-sdk = https://code.soundsoftware.ac.uk/hg/vamp-plugin-sdk |
|
| .hgsubstate | ||
|---|---|---|
| 1 |
5d9af3140f050e99c9ac6c99290dcb55014baf37 vamp-plugin-sdk |
|
| .hgtags | ||
|---|---|---|
| 1 |
b1bc4d045a4be1dc802043d90c54538454fcb2d9 vamp-plugin-tester-v1.0 |
|
| 2 |
eff1772ba3974c163681387c1455bcc9aa853e1f vamp-plugin-tester-v1.0-erroneous |
|
| 3 |
d19bbfc055abb6c7733f9f808b2bd1cd6dfa80c9 vamp-plugin-tester-v1.1 |
|
| CHANGELOG | ||
|---|---|---|
| 1 |
|
|
| 2 |
Changes in Vamp Plugin Tester v1.1 since the previous release v1.0: |
|
| 3 |
|
|
| 4 |
Features |
|
| 5 |
|
|
| 6 |
* Add mechanism for listing the available tests and running only a |
|
| 7 |
single test at a time |
|
| 8 |
|
|
| 9 |
* Add test for reset() changing effective parameter values |
|
| 10 |
|
|
| 11 |
* Add test for fixed-sample-rate output defined without sample rate |
|
| 12 |
|
|
| 13 |
* Add test for existence of .cat file |
|
| 14 |
|
|
| 15 |
* Add test for boilerplate description text still in place for VamPy |
|
| 16 |
plugins |
|
| 17 |
|
|
| 18 |
* Make output more informative for some tests, and make some tests faster |
|
| 19 |
|
|
| 20 |
Bug fixes |
|
| 21 |
|
|
| 22 |
* Fix erroneous verbose timestamp output for some tests |
|
| 23 |
|
|
| 24 |
* Don't complain when two consecutive runs with different starting |
|
| 25 |
times produce the same results, if neither set of results has any |
|
| 26 |
timestamps anyway |
|
| 27 |
|
|
| 28 |
* Link against pthread library on Linux, to support plugins with |
|
| 29 |
threading |
|
| COPYING | ||
|---|---|---|
| 1 |
|
|
| 2 |
Permission is hereby granted, free of charge, to any person |
|
| 3 |
obtaining a copy of this software and associated documentation |
|
| 4 |
files (the "Software"), to deal in the Software without |
|
| 5 |
restriction, including without limitation the rights to use, copy, |
|
| 6 |
modify, merge, publish, distribute, sublicense, and/or sell copies |
|
| 7 |
of the Software, and to permit persons to whom the Software is |
|
| 8 |
furnished to do so, subject to the following conditions: |
|
| 9 |
|
|
| 10 |
The above copyright notice and this permission notice shall be |
|
| 11 |
included in all copies or substantial portions of the Software. |
|
| 12 |
|
|
| 13 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
| 14 |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
| 15 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
| 16 |
NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR |
|
| 17 |
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
|
| 18 |
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
| 19 |
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
| 20 |
|
|
| 21 |
Except as contained in this notice, the names of the Centre for |
|
| 22 |
Digital Music; Queen Mary, University of London; and Chris Cannam |
|
| 23 |
shall not be used in advertising or otherwise to promote the sale, |
|
| 24 |
use or other dealings in this Software without prior written |
|
| 25 |
authorization. |
|
| 26 |
|
|
| Makefile | ||
|---|---|---|
| 1 | 1 |
|
| 2 |
ARCHFLAGS ?= |
|
| 2 |
LDFLAGS += -lvamp-hostsdk -ldl |
|
| 3 |
CXXFLAGS += -Wall -Wextra |
|
| 3 | 4 |
|
| 4 |
LDFLAGS += $(ARCHFLAGS) -ldl -pthread |
|
| 5 |
CXXFLAGS += $(ARCHFLAGS) -g -Wall -Wextra -Ivamp-plugin-sdk -pthread |
|
| 5 |
OBJECTS := vamp-plugin-tester.o Tester.o Test.o TestStaticData.o |
|
| 6 | 6 |
|
| 7 |
# We include the Vamp Host SDK sources in the build here, so that we |
|
| 8 |
# can build the entire thing with debug symbols even though the SDK |
|
| 9 |
# would not normally have them |
|
| 10 |
|
|
| 11 |
VAMP_SRCDIR := vamp-plugin-sdk/src/vamp-hostsdk |
|
| 12 |
|
|
| 13 |
VAMP_OBJECTS := \ |
|
| 14 |
$(VAMP_SRCDIR)/PluginHostAdapter.o \ |
|
| 15 |
$(VAMP_SRCDIR)/RealTime.o \ |
|
| 16 |
$(VAMP_SRCDIR)/PluginBufferingAdapter.o \ |
|
| 17 |
$(VAMP_SRCDIR)/PluginChannelAdapter.o \ |
|
| 18 |
$(VAMP_SRCDIR)/PluginInputDomainAdapter.o \ |
|
| 19 |
$(VAMP_SRCDIR)/PluginLoader.o \ |
|
| 20 |
$(VAMP_SRCDIR)/PluginSummarisingAdapter.o \ |
|
| 21 |
$(VAMP_SRCDIR)/PluginWrapper.o \ |
|
| 22 |
$(VAMP_SRCDIR)/Files.o \ |
|
| 23 |
$(VAMP_SRCDIR)/acsymbols.o |
|
| 24 |
|
|
| 25 |
OBJECTS := \ |
|
| 26 |
$(VAMP_OBJECTS) \ |
|
| 27 |
vamp-plugin-tester.o \ |
|
| 28 |
Tester.o \ |
|
| 29 |
Test.o \ |
|
| 30 |
TestStaticData.o \ |
|
| 31 |
TestInputExtremes.o \ |
|
| 32 |
TestMultipleRuns.o \ |
|
| 33 |
TestOutputs.o \ |
|
| 34 |
TestDefaults.o \ |
|
| 35 |
TestInitialise.o |
|
| 36 |
|
|
| 37 |
vamp-plugin-tester: $(OBJECTS) $(VAMP_OBJECTS) |
|
| 38 |
$(CXX) $(OBJECTS) -o $@ $(LDFLAGS) |
|
| 7 |
vamp-plugin-tester: $(OBJECTS) |
|
| 39 | 8 |
|
| 40 | 9 |
clean: |
| 41 |
rm -f $(OBJECTS) $(VAMP_OBJECTS)
|
|
| 10 |
rm -f $(OBJECTS) |
|
| 42 | 11 |
|
| 43 | 12 |
distclean: clean |
| 44 | 13 |
rm -f *~ vamp-plugin-tester |
| 45 | 14 |
|
| 46 | 15 |
depend: |
| 47 |
makedepend -Y *.cpp *.h $(VAMP_SRCDIR)/*.cpp
|
|
| 16 |
makedepend -Y *.cpp *.h |
|
| 48 | 17 |
|
| 49 | 18 |
# DO NOT DELETE |
| 50 | 19 |
|
| 51 | 20 |
Test.o: Test.h |
| 52 |
TestDefaults.o: TestDefaults.h Test.h Tester.h
|
|
| 21 |
TestStaticData.o: TestStaticData.h Test.h Tester.h
|
|
| 53 | 22 |
Tester.o: Tester.h Test.h |
| 54 |
TestInitialise.o: TestInitialise.h Test.h Tester.h |
|
| 55 |
TestInputExtremes.o: TestInputExtremes.h Test.h Tester.h |
|
| 56 |
TestMultipleRuns.o: TestMultipleRuns.h Test.h Tester.h |
|
| 57 |
TestOutputs.o: TestOutputs.h Test.h Tester.h |
|
| 58 |
TestStaticData.o: TestStaticData.h Test.h Tester.h |
|
| 59 | 23 |
vamp-plugin-tester.o: Tester.h Test.h |
| 60 |
TestDefaults.o: Test.h Tester.h
|
|
| 24 |
TestStaticData.o: Test.h Tester.h
|
|
| 61 | 25 |
Tester.o: Test.h |
| 62 |
TestInitialise.o: Test.h Tester.h |
|
| 63 |
TestInputExtremes.o: Test.h Tester.h |
|
| 64 |
TestMultipleRuns.o: Test.h Tester.h |
|
| 65 |
TestOutputs.o: Test.h Tester.h |
|
| 66 |
TestStaticData.o: Test.h Tester.h |
|
| 67 |
vamp-plugin-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.o: vamp-plugin-sdk/src/vamp-hostsdk/Window.h |
|
| 68 |
vamp-plugin-sdk/src/vamp-hostsdk/PluginInputDomainAdapter.o: vamp-plugin-sdk/src/vamp-sdk/FFTimpl.cpp |
|
| 69 |
vamp-plugin-sdk/src/vamp-hostsdk/RealTime.o: vamp-plugin-sdk/src/vamp-sdk/RealTime.cpp |
|
| README | ||
|---|---|---|
| 1 |
|
|
| 2 |
Vamp Plugin Tester |
|
| 3 |
================== |
|
| 4 |
|
|
| 5 |
This program tests Vamp audio feature extraction plugins |
|
| 6 |
(http://vamp-plugins.org/) for certain common failure cases. |
|
| 7 |
|
|
| 8 |
To test a single plugin, run vamp-plugin-tester with the name of your |
|
| 9 |
plugin library and plugin identifier, separated by a colon. For example, |
|
| 10 |
|
|
| 11 |
$ vamp-plugin-tester vamp-example-plugins:amplitudefollower |
|
| 12 |
|
|
| 13 |
The plugin library must be installed in the Vamp plugin path (you |
|
| 14 |
cannot give the path to the library file). |
|
| 15 |
|
|
| 16 |
|
|
| 17 |
Options |
|
| 18 |
======= |
|
| 19 |
|
|
| 20 |
Supply the -a or --all option to tell vamp-plugin-tester to test all |
|
| 21 |
plugins found in your Vamp path. |
|
| 22 |
|
|
| 23 |
Supply the -v or --verbose option to tell vamp-plugin-tester to print |
|
| 24 |
out the whole content of its returned feature log for diagnostic |
|
| 25 |
purposes each time it prints an error or warning that arises from the |
|
| 26 |
contents of a returned feature. |
|
| 27 |
|
|
| 28 |
Supply the -n or --nondeterministic option to tell vamp-plugin-tester |
|
| 29 |
that your plugins are expected to return different results each time |
|
| 30 |
they are run. The default behaviour is to treat different results on |
|
| 31 |
separate runs with the same input data as an error. |
|
| 32 |
|
|
| 33 |
Supply the -t or --test option with a test ID argument to tell |
|
| 34 |
vamp-plugin-tester to run only a single test, rather than the complete |
|
| 35 |
test suite. To find out what test ID to use for a given test, run |
|
| 36 |
vamp-plugin-tester with the --list-tests or -l option. |
|
| 37 |
|
|
| 38 |
|
|
| 39 |
Errors and Warnings |
|
| 40 |
=================== |
|
| 41 |
|
|
| 42 |
Each test may cause one or several notes, warnings, or errors to be |
|
| 43 |
printed. A note is printed when behaviour is observed that may be |
|
| 44 |
correct behaviour but that is not always anticipated by the plugin |
|
| 45 |
developer. A warning is printed when behaviour is observed that is |
|
| 46 |
technically legal but that in practice most often happens by mistake. |
|
| 47 |
An error is printed when behaviour is observed that cannot be correct. |
|
| 48 |
|
|
| 49 |
vamp-plugin-tester prints all of its commentary to the standard |
|
| 50 |
output. Standard error is usually used for diagnostic output printed |
|
| 51 |
by the plugins themselves. |
|
| 52 |
|
|
| 53 |
In addition to reports, vamp-plugin-tester runs some tests that are |
|
| 54 |
intended to provoke the plugin into unexpected behaviour such as |
|
| 55 |
memory errors. If vamp-plugin-tester crashes during a test, this may |
|
| 56 |
be why. If you have access to a memory checker utility such as |
|
| 57 |
valgrind, you are advised to run vamp-plugin-tester under it so as to |
|
| 58 |
be informed of any memory errors that do not happen to cause crashes |
|
| 59 |
(as well as memory leaks). The vamp-plugin-tester binaries |
|
| 60 |
distributed by QMUL have been compiled with debug information |
|
| 61 |
included, in order to facilitate this type of use. |
|
| 62 |
|
|
| 63 |
|
|
| 64 |
Error and Warning Reference |
|
| 65 |
=========================== |
|
| 66 |
|
|
| 67 |
** ERROR: Failed to load plugin |
|
| 68 |
|
|
| 69 |
The plugin could not be loaded. Remember that the plugin must be |
|
| 70 |
installed in the Vamp plugin path. |
|
| 71 |
|
|
| 72 |
Normally this message will be preceded by one of the following |
|
| 73 |
errors: |
|
| 74 |
|
|
| 75 |
Invalid plugin key <key> in loadPlugin |
|
| 76 |
|
|
| 77 |
- The argument given to vamp-plugin-tester could not be split |
|
| 78 |
into library name and plugin identifier. Check the usage |
|
| 79 |
description above. |
|
| 80 |
|
|
| 81 |
No library found in Vamp path for plugin <key> |
|
| 82 |
|
|
| 83 |
- No Vamp plugin library of that name was found in the Vamp path. |
|
| 84 |
This message will often be accompanied by one of the following |
|
| 85 |
errors; if it isn't, then that probably means the file did not |
|
| 86 |
exist at all. |
|
| 87 |
|
|
| 88 |
Plugin <id> not found in library <name> |
|
| 89 |
|
|
| 90 |
- The library was found and loaded and was apparently a valid |
|
| 91 |
Vamp plugin library, but it didn't contain a plugin of that id. |
|
| 92 |
Check you typed the id correctly, and if this is your library, |
|
| 93 |
check that the vampGetPluginDescriptor function returns the |
|
| 94 |
plugin descriptor properly. |
|
| 95 |
|
|
| 96 |
Unable to load library <name> |
|
| 97 |
|
|
| 98 |
- A dynamic library of that name was found, but the system library |
|
| 99 |
loader could not load it. Perhaps it depends on another library |
|
| 100 |
that is not available, or it was built for the wrong architecture. |
|
| 101 |
There may be more information in the error message. |
|
| 102 |
|
|
| 103 |
No vampGetPluginDescriptor function found in library <name> |
|
| 104 |
|
|
| 105 |
- A dynamic library of that name was found and loaded, but it |
|
| 106 |
lacked the necessary public vampGetPluginDescriptor function. |
|
| 107 |
|
|
| 108 |
* Are you sure this is a Vamp plugin library? |
|
| 109 |
* If you made it, did you remember to include the global |
|
| 110 |
vampGetPluginDescriptor function in your library along with |
|
| 111 |
your plugin classes? |
|
| 112 |
* If you are using Visual C++, did you remember to mark the |
|
| 113 |
vampGetPluginDescriptor symbol exported, as described in |
|
| 114 |
the README.msvc file in the SDK? |
|
| 115 |
|
|
| 116 |
** ERROR: (plugin|parameter|output) identifier <x> contains invalid characters |
|
| 117 |
|
|
| 118 |
An identifier contains characters other than the permitted set (ASCII |
|
| 119 |
lower and upper case letters, digits, "-" and "_" only). |
|
| 120 |
|
|
| 121 |
** ERROR: <field> is empty |
|
| 122 |
|
|
| 123 |
A mandatory field, such as the name of a parameter or output, |
|
| 124 |
contains no text. |
|
| 125 |
|
|
| 126 |
** WARNING: <field> is empty |
|
| 127 |
|
|
| 128 |
An optional field, such as the description of a parameter or output, |
|
| 129 |
contains no text. |
|
| 130 |
|
|
| 131 |
** ERROR: Plugin parameter <x> maxValue <= minValue |
|
| 132 |
|
|
| 133 |
The minimum and maximum values given for a parameter are equal or in |
|
| 134 |
the wrong order. |
|
| 135 |
|
|
| 136 |
** ERROR: Plugin parameter <x> defaultValue out of range |
|
| 137 |
|
|
| 138 |
The default value for a parameter is not within the range defined by |
|
| 139 |
the minimum and maximum values for the parameter. |
|
| 140 |
|
|
| 141 |
** ERROR: Plugin parameter <x> is quantized, but quantize step is zero |
|
| 142 |
|
|
| 143 |
The quantizeStep value in a parameter with isQuantized true is set to |
|
| 144 |
zero. |
|
| 145 |
|
|
| 146 |
** WARNING: Plugin parameter <x> value range is not a multiple of quantize step |
|
| 147 |
|
|
| 148 |
A parameter's stated maximum value is not one of the possible values |
|
| 149 |
obtained by adding multiples of the quantize step on to the minimum |
|
| 150 |
value. |
|
| 151 |
|
|
| 152 |
** WARNING: Plugin parameter <x> has (more|fewer) value names than quantize steps |
|
| 153 |
|
|
| 154 |
A quantized parameter lists some value names for its quantize steps, |
|
| 155 |
but not the right number. |
|
| 156 |
|
|
| 157 |
** WARNING: Plugin parameter <x> default value is not a multiple of quantize |
|
| 158 |
step beyond minimum |
|
| 159 |
|
|
| 160 |
The default value for a parameter is not a value that the user could |
|
| 161 |
actually obtain, if only offered the quantized values to choose from. |
|
| 162 |
|
|
| 163 |
** ERROR: Data returned on nonexistent output |
|
| 164 |
|
|
| 165 |
The output number key for a returned feature is outside the range of |
|
| 166 |
outputs listed in the plugin's output descriptor list. |
|
| 167 |
|
|
| 168 |
** NOTE: No results returned for output <x> |
|
| 169 |
|
|
| 170 |
The plugin returned no features on one of its outputs, when given a |
|
| 171 |
simple test file. This may be perfectly reasonable behaviour, but |
|
| 172 |
you might like to know about it. |
|
| 173 |
|
|
| 174 |
** ERROR: Plugin output <x> has FixedSampleRate but gives sample rate as 0 |
|
| 175 |
|
|
| 176 |
A plugin output that has a sample type of FixedSampleRate must have a |
|
| 177 |
non-zero sample rate. See |
|
| 178 |
https://code.soundsoftware.ac.uk/projects/vamp-plugin-sdk/wiki/SampleType |
|
| 179 |
|
|
| 180 |
** NOTE: Plugin returns features with timestamps on OneSamplePerStep output |
|
| 181 |
** NOTE: Plugin returns features with durations on OneSamplePerStep output |
|
| 182 |
|
|
| 183 |
Hosts will usually ignore timestamps and durations attached to any |
|
| 184 |
feature returned on a OneSamplePerStep output. See |
|
| 185 |
https://code.soundsoftware.ac.uk/projects/vamp-plugin-sdk/wiki/SampleType |
|
| 186 |
|
|
| 187 |
** ERROR: Plugin returns features with no timestamps on VariableSampleRate output |
|
| 188 |
|
|
| 189 |
Timestamps are mandatory on all features associated with a |
|
| 190 |
VariableSampleRate output. See |
|
| 191 |
https://code.soundsoftware.ac.uk/projects/vamp-plugin-sdk/wiki/SampleType |
|
| 192 |
|
|
| 193 |
** WARNING: Plugin returned one or more NaN/inf values |
|
| 194 |
|
|
| 195 |
The plugin returned features containing floating-point not-a-number |
|
| 196 |
or infinity values. This warning may be associated with a test |
|
| 197 |
involving feeding some unexpected type of data to the plugin. |
|
| 198 |
|
|
| 199 |
** ERROR: Consecutive runs with separate instances produce different results |
|
| 200 |
|
|
| 201 |
The plugin was constructed and run twice against the same input data, |
|
| 202 |
and returned different features each time. |
|
| 203 |
|
|
| 204 |
If you give the -n or --nondeterministic option, vamp-plugin-tester |
|
| 205 |
will downgrade this error to a note. |
|
| 206 |
|
|
| 207 |
** ERROR: Consecutive runs with the same instance (using reset) produce different results |
|
| 208 |
|
|
| 209 |
The plugin was constructed, initialised, run against some input data, |
|
| 210 |
reset with a call to its reset() function, and run again against the |
|
| 211 |
same data; and it returned different features on each run. This is |
|
| 212 |
often a sign of some simple error such as forgetting to implement |
|
| 213 |
reset(). |
|
| 214 |
|
|
| 215 |
If you give the -n or --nondeterministic option, vamp-plugin-tester |
|
| 216 |
will downgrade this error to a note. |
|
| 217 |
|
|
| 218 |
** ERROR: Simultaneous runs with separate instances produce different results |
|
| 219 |
|
|
| 220 |
Two instances of the plugin were constructed and run against the same |
|
| 221 |
input data, giving each block of data to one plugin's process call |
|
| 222 |
and then to the other's, "interleaving" the processing between the |
|
| 223 |
two instances (but within a single application thread); and the two |
|
| 224 |
instances returned different features. This may indicate ill-advised |
|
| 225 |
use of static data shared between plugin instances. |
|
| 226 |
|
|
| 227 |
If you give the -n or --nondeterministic option, vamp-plugin-tester |
|
| 228 |
will downgrade this error to a note. |
|
| 229 |
|
|
| 230 |
** WARNING: Consecutive runs with different starting timestamps produce the same result |
|
| 231 |
|
|
| 232 |
The plugin was run twice on the same audio data, but with different |
|
| 233 |
input timestamps, and it returned the same results each time. While |
|
| 234 |
this is often unproblematic, it can indicate that a plugin failed to |
|
| 235 |
take the input timestamp into account when calculating its output |
|
| 236 |
timestamps (if any). |
|
| 237 |
|
|
| 238 |
If you give the -n or --nondeterministic option, vamp-plugin-tester |
|
| 239 |
will downgrade this warning to a note. |
|
| 240 |
|
|
| 241 |
** ERROR: Explicitly setting current program to its supposed current value changes the results |
|
| 242 |
|
|
| 243 |
The plugin was constructed and run twice on the same data, once |
|
| 244 |
without changing its "program" setting, and again having set the |
|
| 245 |
program to the vaule returned by getCurrentProgram() (i.e. the same |
|
| 246 |
program that was supposed to be in effect already). It returned |
|
| 247 |
different results for the two runs, suggesting that some internal |
|
| 248 |
data was changed in selectProgram in a way that differed from its |
|
| 249 |
default. |
|
| 250 |
|
|
| 251 |
If you give the -n or --nondeterministic option, vamp-plugin-tester |
|
| 252 |
will downgrade this error to a note. |
|
| 253 |
|
|
| 254 |
** ERROR: Explicitly setting parameters to their supposed default values changes the results |
|
| 255 |
|
|
| 256 |
The plugin was constructed and run twice on the same data, once |
|
| 257 |
without changing any of its parameters, and again having set the |
|
| 258 |
parameters to their specified default values. It returned different |
|
| 259 |
results for the two runs, suggesting that some internal data was |
|
| 260 |
changed when a parameter was set to its default, in a way that |
|
| 261 |
differed from the plugin's initially constructed state. |
|
| 262 |
|
|
| 263 |
If you give the -n or --nondeterministic option, vamp-plugin-tester |
|
| 264 |
will downgrade this error to a note. |
|
| 265 |
|
|
| 266 |
** ERROR: Call to reset after setting parameters, but before processing, changes the results (parameter values not retained through reset?) |
|
| 267 |
|
|
| 268 |
The plugin was constructed and run twice on the same data. The first |
|
| 269 |
time, its parameters were set to some arbitrary values and it was |
|
| 270 |
initialised and run. The second time, its parameters were set to the |
|
| 271 |
same values and it was initialised, then reset(), then run. The two |
|
| 272 |
runs returned different results, suggesting that perhaps some |
|
| 273 |
parameter value was being modified within the reset() function. (This |
|
| 274 |
function should reset internal state within the plugin, but not |
|
| 275 |
parameter configuration.) |
|
| 276 |
|
|
| 277 |
If you give the -n or --nondeterministic option, vamp-plugin-tester |
|
| 278 |
will downgrade this error to a note. |
|
| 279 |
|
|
| 280 |
** WARNING: Constructor takes some time to run: work should be deferred to initialise? |
|
| 281 |
|
|
| 282 |
The plugin took a long time to construct. You should ensure that the |
|
| 283 |
constructor for the plugin runs as quickly as possible, because it |
|
| 284 |
may be called by a host that is only scanning the properties of all |
|
| 285 |
available plugins on startup. Any serious initialisation work should |
|
| 286 |
be done in the initialise() function rather than the constructor. |
|
| 287 |
|
|
| 288 |
|
|
| 289 |
Authors |
|
| 290 |
======= |
|
| 291 |
|
|
| 292 |
This program was written at the Centre for Digital Music at Queen |
|
| 293 |
Mary, University of London, by Chris Cannam. Copyright (c) 2009-2015 QMUL. |
|
| 294 |
|
|
| Test.cpp | ||
|---|---|---|
| 4 | 4 |
Vamp Plugin Fuzz Tester |
| 5 | 5 |
Chris Cannam, cannam@all-day-breakfast.com |
| 6 | 6 |
Centre for Digital Music, Queen Mary, University of London. |
| 7 |
Copyright 2009-2014 QMUL.
|
|
| 7 |
Copyright 2009 QMUL. |
|
| 8 | 8 |
|
| 9 | 9 |
This program loads a Vamp plugin and tests its susceptibility to a |
| 10 | 10 |
number of common pitfalls, including handling of extremes of input |
| ... | ... | |
| 44 | 44 |
using namespace Vamp; |
| 45 | 45 |
using namespace Vamp::HostExt; |
| 46 | 46 |
|
| 47 |
#include <math.h> |
|
| 48 |
|
|
| 49 |
#ifdef __SUNPRO_CC |
|
| 50 |
#include <ieeefp.h> |
|
| 51 |
#define isinf(x) (!finite(x)) |
|
| 52 |
#endif |
|
| 53 |
|
|
| 54 | 47 |
Test::Test() { }
|
| 55 | 48 |
Test::~Test() { }
|
| 56 | 49 |
|
| 57 |
using std::cerr; |
|
| 58 |
using std::cout; |
|
| 59 |
using std::endl; |
|
| 60 |
using std::string; |
|
| 61 |
|
|
| 62 | 50 |
Plugin * |
| 63 |
Test::load(string key, float rate) |
|
| 51 |
Test::load(std::string key, float rate)
|
|
| 64 | 52 |
{
|
| 65 |
Plugin *p = PluginLoader::getInstance()->loadPlugin
|
|
| 53 |
return PluginLoader::getInstance()->loadPlugin
|
|
| 66 | 54 |
(key, rate, PluginLoader::ADAPT_ALL); |
| 67 |
if (!p) throw FailedToLoadPlugin(); |
|
| 68 |
return p; |
|
| 69 |
} |
|
| 70 |
|
|
| 71 |
float ** |
|
| 72 |
Test::createBlock(size_t channels, size_t blocksize) |
|
| 73 |
{
|
|
| 74 |
float **b = new float *[channels]; |
|
| 75 |
for (size_t c = 0; c < channels; ++c) {
|
|
| 76 |
b[c] = new float[blocksize]; |
|
| 77 |
} |
|
| 78 |
return b; |
|
| 79 |
} |
|
| 80 |
|
|
| 81 |
void |
|
| 82 |
Test::destroyBlock(float **blocks, size_t channels) |
|
| 83 |
{
|
|
| 84 |
for (size_t c = 0; c < channels; ++c) {
|
|
| 85 |
delete[] blocks[c]; |
|
| 86 |
} |
|
| 87 |
delete[] blocks; |
|
| 88 |
} |
|
| 89 |
|
|
| 90 |
float ** |
|
| 91 |
Test::createTestAudio(size_t channels, size_t blocksize, size_t blocks) |
|
| 92 |
{
|
|
| 93 |
float **b = new float *[channels]; |
|
| 94 |
for (size_t c = 0; c < channels; ++c) {
|
|
| 95 |
b[c] = new float[blocksize * blocks]; |
|
| 96 |
for (int i = 0; i < int(blocksize * blocks); ++i) {
|
|
| 97 |
b[c][i] = sinf(float(i) / 10.f); |
|
| 98 |
if (i == 5005 || i == 20002) {
|
|
| 99 |
b[c][i-2] = 0; |
|
| 100 |
b[c][i-1] = -1; |
|
| 101 |
b[c][i] = 1; |
|
| 102 |
} |
|
| 103 |
} |
|
| 104 |
} |
|
| 105 |
return b; |
|
| 106 |
} |
|
| 107 |
|
|
| 108 |
void |
|
| 109 |
Test::destroyTestAudio(float **b, size_t channels) |
|
| 110 |
{
|
|
| 111 |
for (size_t c = 0; c < channels; ++c) {
|
|
| 112 |
delete[] b[c]; |
|
| 113 |
} |
|
| 114 |
delete[] b; |
|
| 115 |
} |
|
| 116 |
|
|
| 117 |
bool |
|
| 118 |
Test::initDefaults(Plugin *p, size_t &channels, size_t &step, size_t &block, |
|
| 119 |
Results &r) |
|
| 120 |
{
|
|
| 121 |
channels = p->getMinChannelCount(); |
|
| 122 |
block = p->getPreferredBlockSize(); |
|
| 123 |
step = p->getPreferredStepSize(); |
|
| 124 |
if (block == 0) block = 1024; |
|
| 125 |
if (step == 0) {
|
|
| 126 |
if (p->getInputDomain() == Plugin::FrequencyDomain) step = block/2; |
|
| 127 |
else step = block; |
|
| 128 |
} |
|
| 129 |
if (!p->initialise(channels, step, block)) {
|
|
| 130 |
r.push_back(error("initialisation with default values failed"));
|
|
| 131 |
return false; |
|
| 132 |
} |
|
| 133 |
return true; |
|
| 134 |
} |
|
| 135 |
|
|
| 136 |
bool |
|
| 137 |
Test::initAdapted(Plugin *p, size_t &channels, size_t step, size_t block, |
|
| 138 |
Results &r) |
|
| 139 |
{
|
|
| 140 |
channels = p->getMinChannelCount(); |
|
| 141 |
if (!p->initialise(channels, step, block)) {
|
|
| 142 |
r.push_back(error("initialisation failed"));
|
|
| 143 |
return false; |
|
| 144 |
} |
|
| 145 |
return true; |
|
| 146 | 55 |
} |
| 147 | 56 |
|
| 148 | 57 |
void |
| ... | ... | |
| 159 | 68 |
} |
| 160 | 69 |
|
| 161 | 70 |
bool |
| 162 |
Test::allFeaturesValid(const Plugin::FeatureSet &b) |
|
| 163 |
{
|
|
| 164 |
for (Plugin::FeatureSet::const_iterator i = b.begin(); i != b.end(); ++i) {
|
|
| 165 |
for (int j = 0; j < (int)i->second.size(); ++j) {
|
|
| 166 |
if (i->second[j].values.empty()) continue; |
|
| 167 |
for (int k = 0; k < (int)i->second[j].values.size(); ++k) {
|
|
| 168 |
if (isnan(i->second[j].values[k]) || |
|
| 169 |
isinf(i->second[j].values[k])) {
|
|
| 170 |
return false; |
|
| 171 |
} |
|
| 172 |
} |
|
| 173 |
} |
|
| 174 |
} |
|
| 175 |
return true; |
|
| 176 |
} |
|
| 177 |
|
|
| 178 |
bool |
|
| 179 |
Test::containsTimestamps(const Plugin::FeatureSet &b) |
|
| 180 |
{
|
|
| 181 |
for (Plugin::FeatureSet::const_iterator i = b.begin(); i != b.end(); ++i) {
|
|
| 182 |
for (int j = 0; j < (int)i->second.size(); ++j) {
|
|
| 183 |
if (i->second[j].values.empty()) continue; |
|
| 184 |
for (int k = 0; k < (int)i->second[j].values.size(); ++k) {
|
|
| 185 |
if (i->second[j].hasTimestamp) {
|
|
| 186 |
return true; |
|
| 187 |
} |
|
| 188 |
} |
|
| 189 |
} |
|
| 190 |
} |
|
| 191 |
return false; |
|
| 192 |
} |
|
| 193 |
|
|
| 194 |
void |
|
| 195 |
Test::dumpFeature(const Plugin::Feature &f, bool showValues, |
|
| 196 |
const Plugin::Feature *other) |
|
| 197 |
{
|
|
| 198 |
cout << " Timestamp: " << (!f.hasTimestamp ? "(none)" : f.timestamp.toText()) << endl; |
|
| 199 |
cout << " Duration: " << (!f.hasDuration ? "(none)" : f.duration.toText()) << endl; |
|
| 200 |
cout << " Label: " << (f.label == "" ? "(none)" : f.label) << endl; |
|
| 201 |
if (showValues) {
|
|
| 202 |
cout << " Values (" << f.values.size() << "): " << (f.values.empty() ? "(none)" : "");
|
|
| 203 |
int n = f.values.size(); |
|
| 204 |
if (!other) {
|
|
| 205 |
for (int j = 0; j < n; ++j) {
|
|
| 206 |
cout << f.values[j] << " "; |
|
| 207 |
} |
|
| 208 |
} else {
|
|
| 209 |
int samecount = 0; |
|
| 210 |
int diffcount = 0; |
|
| 211 |
for (int j = 0; j <= n; ++j) {
|
|
| 212 |
if (j < n && f.values[j] == other->values[j]) {
|
|
| 213 |
++samecount; |
|
| 214 |
} else {
|
|
| 215 |
if (samecount > 0) {
|
|
| 216 |
cout << "(" << samecount << " identical) ";
|
|
| 217 |
} |
|
| 218 |
samecount = 0; |
|
| 219 |
if (j < n) {
|
|
| 220 |
++diffcount; |
|
| 221 |
if (diffcount > 20 && j + 10 < n) {
|
|
| 222 |
cout << "(remaining " << n - j << " values elided)"; |
|
| 223 |
break; |
|
| 224 |
} else {
|
|
| 225 |
cout << f.values[j] << " [diff " |
|
| 226 |
<< f.values[j] - other->values[j] << "] "; |
|
| 227 |
} |
|
| 228 |
} |
|
| 229 |
} |
|
| 230 |
} |
|
| 231 |
} |
|
| 232 |
cout << endl; |
|
| 233 |
} else {
|
|
| 234 |
cout << " Values (" << f.values.size() << "): (elided)" << endl;
|
|
| 235 |
} |
|
| 236 |
} |
|
| 237 |
|
|
| 238 |
void |
|
| 239 |
Test::dump(const Plugin::FeatureSet &fs, bool showValues) |
|
| 240 |
{
|
|
| 241 |
for (Plugin::FeatureSet::const_iterator fsi = fs.begin(); |
|
| 242 |
fsi != fs.end(); ++fsi) {
|
|
| 243 |
int output = fsi->first; |
|
| 244 |
cout << "Output " << output << ":" << endl; |
|
| 245 |
const Plugin::FeatureList &fl = fsi->second; |
|
| 246 |
for (int i = 0; i < (int)fl.size(); ++i) {
|
|
| 247 |
cout << " Feature " << i << ":" << endl; |
|
| 248 |
const Plugin::Feature &f = fl[i]; |
|
| 249 |
dumpFeature(f, showValues); |
|
| 250 |
} |
|
| 251 |
} |
|
| 252 |
} |
|
| 253 |
|
|
| 254 |
void |
|
| 255 |
Test::dumpTwo(const Result &r, |
|
| 256 |
const Plugin::FeatureSet &a, |
|
| 257 |
const Plugin::FeatureSet &b) |
|
| 258 |
{
|
|
| 259 |
std::cout << r.message() << std::endl; |
|
| 260 |
std::cout << "\nFirst result set:" << std::endl; |
|
| 261 |
dump(a, false); |
|
| 262 |
std::cout << "\nSecond result set:" << std::endl; |
|
| 263 |
dump(b, false); |
|
| 264 |
std::cout << std::endl; |
|
| 265 |
} |
|
| 266 |
|
|
| 267 |
void |
|
| 268 |
Test::dumpDiff(const Result &r, |
|
| 269 |
const Plugin::FeatureSet &a, |
|
| 270 |
const Plugin::FeatureSet &b) |
|
| 271 |
{
|
|
| 272 |
cout << r.message() << endl; |
|
| 273 |
cout << "\nDifferences follow:" << endl; |
|
| 274 |
if (a.size() != b.size()) {
|
|
| 275 |
cout << "*** First result set has features on " << a.size() |
|
| 276 |
<< " output(s), second has features on " << b.size() |
|
| 277 |
<< endl; |
|
| 278 |
return; |
|
| 279 |
} |
|
| 280 |
Plugin::FeatureSet::const_iterator ai = a.begin(); |
|
| 281 |
Plugin::FeatureSet::const_iterator bi = b.begin(); |
|
| 282 |
while (ai != a.end()) {
|
|
| 283 |
if (ai->first != bi->first) {
|
|
| 284 |
cout << "\n*** Output number mismatch: first result set says " |
|
| 285 |
<< ai->first << " where second says " << bi->first |
|
| 286 |
<< endl; |
|
| 287 |
} else {
|
|
| 288 |
cout << "\nOutput " << ai->first << ":" << endl; |
|
| 289 |
if (ai->second.size() != bi->second.size()) {
|
|
| 290 |
cout << "*** First result set has " << ai->second.size() |
|
| 291 |
<< " feature(s) on this output, second has " |
|
| 292 |
<< bi->second.size() << endl; |
|
| 293 |
} else {
|
|
| 294 |
int fno = 0; |
|
| 295 |
int diffcount = 0; |
|
| 296 |
Plugin::FeatureList::const_iterator afi = ai->second.begin(); |
|
| 297 |
Plugin::FeatureList::const_iterator bfi = bi->second.begin(); |
|
| 298 |
while (afi != ai->second.end()) {
|
|
| 299 |
if (!(*afi == *bfi)) {
|
|
| 300 |
if (diffcount == 0) {
|
|
| 301 |
bool differInValues = |
|
| 302 |
(afi->values.size() == bfi->values.size() && |
|
| 303 |
afi->values != bfi->values); |
|
| 304 |
if (afi->hasTimestamp != bfi->hasTimestamp) {
|
|
| 305 |
cout << "*** Feature " << fno << " differs in presence of timestamp (" << afi->hasTimestamp << " vs " << bfi->hasTimestamp << ")" << endl;
|
|
| 306 |
} |
|
| 307 |
if (afi->hasTimestamp && (afi->timestamp != bfi->timestamp)) {
|
|
| 308 |
cout << "*** Feature " << fno << " differs in timestamp (" << afi->timestamp << " vs " << bfi->timestamp << " )" << endl;
|
|
| 309 |
} |
|
| 310 |
if (afi->hasDuration != bfi->hasDuration) {
|
|
| 311 |
cout << "*** Feature " << fno << " differs in presence of duration (" << afi->hasDuration << " vs " << bfi->hasDuration << ")" << endl;
|
|
| 312 |
} |
|
| 313 |
if (afi->hasDuration && (afi->duration != bfi->duration)) {
|
|
| 314 |
cout << "*** Feature " << fno << " differs in duration (" << afi->duration << " vs " << bfi->duration << " )" << endl;
|
|
| 315 |
} |
|
| 316 |
if (afi->label != bfi->label) {
|
|
| 317 |
cout << "*** Feature " << fno << " differs in label" << endl; |
|
| 318 |
} |
|
| 319 |
if (afi->values.size() != bfi->values.size()) {
|
|
| 320 |
cout << "*** Feature " << fno << " differs in number of values (" << afi->values.size() << " vs " << bfi->values.size() << ")" << endl;
|
|
| 321 |
} |
|
| 322 |
if (differInValues) {
|
|
| 323 |
cout << "*** Feature " << fno << " differs in values" << endl; |
|
| 324 |
} |
|
| 325 |
cout << " First output:" << endl; |
|
| 326 |
dumpFeature(*afi, differInValues); |
|
| 327 |
cout << " Second output:" << endl; |
|
| 328 |
dumpFeature(*bfi, differInValues, &(*afi)); |
|
| 329 |
} |
|
| 330 |
++diffcount; |
|
| 331 |
} |
|
| 332 |
++fno; |
|
| 333 |
++afi; |
|
| 334 |
++bfi; |
|
| 335 |
} |
|
| 336 |
if (diffcount > 1) {
|
|
| 337 |
cout << diffcount-1 << " subsequent differing feature(s) elided" << endl; |
|
| 338 |
} |
|
| 339 |
} |
|
| 340 |
} |
|
| 341 |
++ai; |
|
| 342 |
++bi; |
|
| 343 |
} |
|
| 344 |
cout << endl; |
|
| 345 |
} |
|
| 346 |
|
|
| 347 |
bool |
|
| 348 | 71 |
operator==(const Plugin::FeatureSet &a, const Plugin::FeatureSet &b) |
| 349 | 72 |
{
|
| 350 | 73 |
if (a.size() != b.size()) return false; |
| Test.h | ||
|---|---|---|
| 4 | 4 |
Vamp Plugin Tester |
| 5 | 5 |
Chris Cannam, cannam@all-day-breakfast.com |
| 6 | 6 |
Centre for Digital Music, Queen Mary, University of London. |
| 7 |
Copyright 2009-2014 QMUL.
|
|
| 7 |
Copyright 2009 QMUL. |
|
| 8 | 8 |
|
| 9 | 9 |
This program loads a Vamp plugin and tests its susceptibility to a |
| 10 | 10 |
number of common pitfalls, including handling of extremes of input |
| ... | ... | |
| 48 | 48 |
{
|
| 49 | 49 |
public: |
| 50 | 50 |
virtual ~Test(); |
| 51 |
|
|
| 52 |
enum Option {
|
|
| 53 |
NoOption = 0x0, |
|
| 54 |
NonDeterministic = 0x1, |
|
| 55 |
Verbose = 0x2, |
|
| 56 |
SingleTest = 0x4 |
|
| 57 |
}; |
|
| 58 |
typedef int Options; |
|
| 59 | 51 |
|
| 60 | 52 |
class Result {
|
| 61 | 53 |
|
| 62 | 54 |
public: |
| 63 |
enum Code { Success, Note, Warning, Error };
|
|
| 55 |
enum Code { Success, Warning, Error };
|
|
| 64 | 56 |
|
| 65 |
Result() : m_code(Success) { }
|
|
| 66 | 57 |
Result(Code c, std::string m) : m_code(c), m_message(m) { }
|
| 67 | 58 |
|
| 68 |
Code code() const { return m_code; }
|
|
| 69 |
std::string message() const { return m_message; }
|
|
| 70 |
|
|
| 59 |
Code code() { return m_code; }
|
|
| 60 |
std::string message() { return m_message; }
|
|
| 61 |
|
|
| 71 | 62 |
protected: |
| 72 | 63 |
Code m_code; |
| 73 | 64 |
std::string m_message; |
| 74 | 65 |
}; |
| 75 | 66 |
|
| 76 | 67 |
static Result success() { return Result(Result::Success, ""); }
|
| 77 |
static Result note(std::string m) { return Result(Result::Note, m); }
|
|
| 78 | 68 |
static Result warning(std::string m) { return Result(Result::Warning, m); }
|
| 79 | 69 |
static Result error(std::string m) { return Result(Result::Error, m); }
|
| 80 | 70 |
|
| ... | ... | |
| 83 | 73 |
class FailedToLoadPlugin { };
|
| 84 | 74 |
|
| 85 | 75 |
// may throw FailedToLoadPlugin |
| 86 |
virtual Results test(std::string key, Options) = 0;
|
|
| 76 |
virtual Results test(std::string key) = 0; |
|
| 87 | 77 |
|
| 88 | 78 |
protected: |
| 89 | 79 |
Test(); |
| ... | ... | |
| 91 | 81 |
// may throw FailedToLoadPlugin |
| 92 | 82 |
Vamp::Plugin *load(std::string key, float rate = 44100); |
| 93 | 83 |
|
| 94 |
float **createBlock(size_t channels, size_t blocksize); |
|
| 95 |
void destroyBlock(float **blocks, size_t channels); |
|
| 96 |
|
|
| 97 |
float **createTestAudio(size_t channels, size_t blocksize, size_t blocks); |
|
| 98 |
void destroyTestAudio(float **audio, size_t channels); |
|
| 99 |
|
|
| 100 |
// use plugin's preferred step/block size, return them: |
|
| 101 |
bool initDefaults(Vamp::Plugin *, size_t &channels, |
|
| 102 |
size_t &step, size_t &block, Results &r); |
|
| 103 |
|
|
| 104 |
// use the given step/block size and an adapter: |
|
| 105 |
bool initAdapted(Vamp::Plugin *, size_t &channels, |
|
| 106 |
size_t step, size_t block, Results &r); |
|
| 107 |
|
|
| 108 | 84 |
void appendFeatures(Vamp::Plugin::FeatureSet &a, |
| 109 | 85 |
const Vamp::Plugin::FeatureSet &b); |
| 110 |
|
|
| 111 |
bool allFeaturesValid(const Vamp::Plugin::FeatureSet &); // i.e. no NaN/inf |
|
| 112 |
|
|
| 113 |
bool containsTimestamps(const Vamp::Plugin::FeatureSet &); |
|
| 114 |
|
|
| 115 |
void dumpFeature(const Vamp::Plugin::Feature &, bool showValues, |
|
| 116 |
const Vamp::Plugin::Feature *other = 0); |
|
| 117 |
void dump(const Vamp::Plugin::FeatureSet &, bool showValues = true); |
|
| 118 |
void dumpTwo(const Result &r, |
|
| 119 |
const Vamp::Plugin::FeatureSet &, |
|
| 120 |
const Vamp::Plugin::FeatureSet &); |
|
| 121 |
void dumpDiff(const Result &r, |
|
| 122 |
const Vamp::Plugin::FeatureSet &, |
|
| 123 |
const Vamp::Plugin::FeatureSet &); |
|
| 124 | 86 |
}; |
| 125 | 87 |
|
| 126 | 88 |
extern bool operator==(const Vamp::Plugin::FeatureSet &a, |
| TestDefaults.cpp | ||
|---|---|---|
| 1 |
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
|
| 2 |
|
|
| 3 |
/* |
|
| 4 |
Vamp Plugin Tester |
|
| 5 |
Chris Cannam, cannam@all-day-breakfast.com |
|
| 6 |
Centre for Digital Music, Queen Mary, University of London. |
|
| 7 |
Copyright 2009-2014 QMUL. |
|
| 8 |
|
|
| 9 |
This program loads a Vamp plugin and tests its susceptibility to a |
|
| 10 |
number of common pitfalls, including handling of extremes of input |
|
| 11 |
data. If you can think of any additional useful tests that are |
|
| 12 |
easily added, please send them to me. |
|
| 13 |
|
|
| 14 |
Permission is hereby granted, free of charge, to any person |
|
| 15 |
obtaining a copy of this software and associated documentation |
|
| 16 |
files (the "Software"), to deal in the Software without |
|
| 17 |
restriction, including without limitation the rights to use, copy, |
|
| 18 |
modify, merge, publish, distribute, sublicense, and/or sell copies |
|
| 19 |
of the Software, and to permit persons to whom the Software is |
|
| 20 |
furnished to do so, subject to the following conditions: |
|
| 21 |
|
|
| 22 |
The above copyright notice and this permission notice shall be |
|
| 23 |
included in all copies or substantial portions of the Software. |
|
| 24 |
|
|
| 25 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
| 26 |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
| 27 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
| 28 |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR |
|
| 29 |
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
|
| 30 |
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
| 31 |
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
| 32 |
|
|
| 33 |
Except as contained in this notice, the names of the Centre for |
|
| 34 |
Digital Music; Queen Mary, University of London; and Chris Cannam |
|
| 35 |
shall not be used in advertising or otherwise to promote the sale, |
|
| 36 |
use or other dealings in this Software without prior written |
|
| 37 |
authorization. |
|
| 38 |
*/ |
|
| 39 |
|
|
| 40 |
#include "TestDefaults.h" |
|
| 41 |
|
|
| 42 |
#include <vamp-hostsdk/Plugin.h> |
|
| 43 |
using namespace Vamp; |
|
| 44 |
|
|
| 45 |
#include <memory> |
|
| 46 |
using namespace std; |
|
| 47 |
|
|
| 48 |
#include <cmath> |
|
| 49 |
#include <time.h> |
|
| 50 |
|
|
| 51 |
#ifndef __GNUC__ |
|
| 52 |
#include <alloca.h> |
|
| 53 |
#endif |
|
| 54 |
|
|
| 55 |
Tester::TestRegistrar<TestDefaultProgram> |
|
| 56 |
TestDefaultProgram::m_registrar("E1", "Inconsistent default program");
|
|
| 57 |
|
|
| 58 |
Tester::TestRegistrar<TestDefaultParameters> |
|
| 59 |
TestDefaultParameters::m_registrar("E2", "Inconsistent default parameters");
|
|
| 60 |
|
|
| 61 |
Tester::TestRegistrar<TestParametersOnReset> |
|
| 62 |
TestParametersOnReset::m_registrar("E3", "Parameter retention through reset");
|
|
| 63 |
|
|
| 64 |
static const size_t _step = 1000; |
|
| 65 |
|
|
| 66 |
Test::Results |
|
| 67 |
TestDefaultProgram::test(string key, Options options) |
|
| 68 |
{
|
|
| 69 |
Plugin::FeatureSet f[2]; |
|
| 70 |
int rate = 44100; |
|
| 71 |
Results r; |
|
| 72 |
float **data = 0; |
|
| 73 |
size_t channels = 0; |
|
| 74 |
size_t count = 100; |
|
| 75 |
|
|
| 76 |
for (int run = 0; run < 2; ++run) {
|
|
| 77 |
auto_ptr<Plugin> p(load(key, rate)); |
|
| 78 |
if (p->getPrograms().empty()) return r; |
|
| 79 |
if (run == 1) {
|
|
| 80 |
p->selectProgram(p->getCurrentProgram()); |
|
| 81 |
} |
|
| 82 |
if (!initAdapted(p.get(), channels, _step, _step, r)) return r; |
|
| 83 |
if (!data) data = createTestAudio(channels, _step, count); |
|
| 84 |
for (size_t i = 0; i < count; ++i) {
|
|
| 85 |
#ifdef __GNUC__ |
|
| 86 |
float *ptr[channels]; |
|
| 87 |
#else |
|
| 88 |
float **ptr = (float **)alloca(channels * sizeof(float)); |
|
| 89 |
#endif |
|
| 90 |
size_t idx = i * _step; |
|
| 91 |
for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx; |
|
| 92 |
RealTime timestamp = RealTime::frame2RealTime(idx, rate); |
|
| 93 |
Plugin::FeatureSet fs = p->process(ptr, timestamp); |
|
| 94 |
appendFeatures(f[run], fs); |
|
| 95 |
} |
|
| 96 |
Plugin::FeatureSet fs = p->getRemainingFeatures(); |
|
| 97 |
appendFeatures(f[run], fs); |
|
| 98 |
} |
|
| 99 |
if (data) destroyTestAudio(data, channels); |
|
| 100 |
|
|
| 101 |
if (!(f[0] == f[1])) {
|
|
| 102 |
string message = "Explicitly setting current program to its supposed current value changes the results"; |
|
| 103 |
Result res; |
|
| 104 |
if (options & NonDeterministic) res = note(message); |
|
| 105 |
else res = error(message); |
|
| 106 |
if (options & Verbose) dumpDiff(res, f[0], f[1]); |
|
| 107 |
r.push_back(res); |
|
| 108 |
} else {
|
|
| 109 |
r.push_back(success()); |
|
| 110 |
} |
|
| 111 |
|
|
| 112 |
return r; |
|
| 113 |
} |
|
| 114 |
|
|
| 115 |
Test::Results |
|
| 116 |
TestDefaultParameters::test(string key, Options options) |
|
| 117 |
{
|
|
| 118 |
Plugin::FeatureSet f[2]; |
|
| 119 |
int rate = 44100; |
|
| 120 |
Results r; |
|
| 121 |
float **data = 0; |
|
| 122 |
size_t channels = 0; |
|
| 123 |
size_t count = 100; |
|
| 124 |
|
|
| 125 |
for (int run = 0; run < 2; ++run) {
|
|
| 126 |
auto_ptr<Plugin> p(load(key, rate)); |
|
| 127 |
if (p->getParameterDescriptors().empty()) return r; |
|
| 128 |
if (run == 1) {
|
|
| 129 |
Plugin::ParameterList pl = p->getParameterDescriptors(); |
|
| 130 |
for (int i = 0; i < (int)pl.size(); ++i) {
|
|
| 131 |
if (p->getParameter(pl[i].identifier) != pl[i].defaultValue) {
|
|
| 132 |
if (options & Verbose) {
|
|
| 133 |
cout << "Parameter: " << pl[i].identifier << endl; |
|
| 134 |
cout << "Expected: " << pl[i].defaultValue << endl; |
|
| 135 |
cout << "Actual: " << p->getParameter(pl[i].identifier) << endl; |
|
| 136 |
} |
|
| 137 |
r.push_back(error("Not all parameters have their default values when queried directly after construction"));
|
|
| 138 |
} |
|
| 139 |
p->setParameter(pl[i].identifier, pl[i].defaultValue); |
|
| 140 |
} |
|
| 141 |
} |
|
| 142 |
if (!initAdapted(p.get(), channels, _step, _step, r)) return r; |
|
| 143 |
if (!data) data = createTestAudio(channels, _step, count); |
|
| 144 |
for (size_t i = 0; i < count; ++i) {
|
|
| 145 |
#ifdef __GNUC__ |
|
| 146 |
float *ptr[channels]; |
|
| 147 |
#else |
|
| 148 |
float **ptr = (float **)alloca(channels * sizeof(float)); |
|
| 149 |
#endif |
|
| 150 |
size_t idx = i * _step; |
|
| 151 |
for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx; |
|
| 152 |
RealTime timestamp = RealTime::frame2RealTime(idx, rate); |
|
| 153 |
Plugin::FeatureSet fs = p->process(ptr, timestamp); |
|
| 154 |
appendFeatures(f[run], fs); |
|
| 155 |
} |
|
| 156 |
Plugin::FeatureSet fs = p->getRemainingFeatures(); |
|
| 157 |
appendFeatures(f[run], fs); |
|
| 158 |
} |
|
| 159 |
if (data) destroyTestAudio(data, channels); |
|
| 160 |
|
|
| 161 |
if (!(f[0] == f[1])) {
|
|
| 162 |
string message = "Explicitly setting parameters to their supposed default values changes the results"; |
|
| 163 |
Result res; |
|
| 164 |
if (options & NonDeterministic) res = note(message); |
|
| 165 |
else res = error(message); |
|
| 166 |
if (options & Verbose) dumpDiff(res, f[0], f[1]); |
|
| 167 |
r.push_back(res); |
|
| 168 |
} else {
|
|
| 169 |
r.push_back(success()); |
|
| 170 |
} |
|
| 171 |
|
|
| 172 |
return r; |
|
| 173 |
} |
|
| 174 |
|
|
| 175 |
Test::Results |
|
| 176 |
TestParametersOnReset::test(string key, Options options) |
|
| 177 |
{
|
|
| 178 |
Plugin::FeatureSet f[2]; |
|
| 179 |
int rate = 44100; |
|
| 180 |
Results r; |
|
| 181 |
float **data = 0; |
|
| 182 |
size_t channels = 0; |
|
| 183 |
size_t count = 100; |
|
| 184 |
|
|
| 185 |
for (int run = 0; run < 2; ++run) {
|
|
| 186 |
auto_ptr<Plugin> p(load(key, rate)); |
|
| 187 |
if (p->getParameterDescriptors().empty()) return r; |
|
| 188 |
|
|
| 189 |
// Set all parameters to non-default values |
|
| 190 |
|
|
| 191 |
Plugin::ParameterList pl = p->getParameterDescriptors(); |
|
| 192 |
|
|
| 193 |
for (int i = 0; i < (int)pl.size(); ++i) {
|
|
| 194 |
|
|
| 195 |
// Half-way between default and max value, seems a |
|
| 196 |
// reasonable guess for something to set it to. We want to |
|
| 197 |
// avoid the real extremes because they can sometimes be |
|
| 198 |
// very slow, and we want to avoid setting everything to |
|
| 199 |
// the same values (e.g. min) because plugins will |
|
| 200 |
// sometimes legitimately reject that. |
|
| 201 |
|
|
| 202 |
// Remember to take into account quantization |
|
| 203 |
|
|
| 204 |
float value = (pl[i].defaultValue + pl[i].maxValue) / 2; |
|
| 205 |
|
|
| 206 |
if (pl[i].isQuantized) {
|
|
| 207 |
value = round(value / pl[i].quantizeStep) * pl[i].quantizeStep; |
|
| 208 |
} |
|
| 209 |
|
|
| 210 |
if (value > pl[i].maxValue) {
|
|
| 211 |
value = pl[i].maxValue; |
|
| 212 |
} |
|
| 213 |
if (value < pl[i].minValue) {
|
|
| 214 |
value = pl[i].minValue; |
|
| 215 |
} |
|
| 216 |
if (value == pl[i].defaultValue) {
|
|
| 217 |
if (pl[i].defaultValue == pl[i].minValue) {
|
|
| 218 |
value = pl[i].maxValue; |
|
| 219 |
} else {
|
|
| 220 |
value = pl[i].minValue; |
|
| 221 |
} |
|
| 222 |
} |
|
| 223 |
|
|
| 224 |
p->setParameter(pl[i].identifier, value); |
|
| 225 |
} |
|
| 226 |
|
|
| 227 |
if (!initAdapted(p.get(), channels, _step, _step, r)) {
|
|
| 228 |
|
|
| 229 |
// OK, plugin didn't like that. Let's try a different tack |
|
| 230 |
// -- set everything to min except those parameters whose |
|
| 231 |
// default is min, and set those to half way instead |
|
| 232 |
|
|
| 233 |
for (int i = 0; i < (int)pl.size(); ++i) {
|
|
| 234 |
float value = pl[i].minValue; |
|
| 235 |
if (value == pl[i].defaultValue) {
|
|
| 236 |
value = (pl[i].maxValue + pl[i].minValue) / 2; |
|
| 237 |
value = ceil(value / pl[i].quantizeStep) * pl[i].quantizeStep; |
|
| 238 |
if (value > pl[i].maxValue) {
|
|
| 239 |
value = pl[i].maxValue; |
|
| 240 |
} |
|
| 241 |
} |
|
| 242 |
p->setParameter(pl[i].identifier, value); |
|
| 243 |
} |
|
| 244 |
|
|
| 245 |
r = Results(); |
|
| 246 |
if (!initAdapted(p.get(), channels, _step, _step, r)) {
|
|
| 247 |
// Still didn't work, give up |
|
| 248 |
return r; |
|
| 249 |
} |
|
| 250 |
} |
|
| 251 |
|
|
| 252 |
// First run: construct, set params, init, process |
|
| 253 |
// Second run: construct, set params, init, reset, process |
|
| 254 |
// We expect these to produce the same results |
|
| 255 |
if (run == 1) p->reset(); |
|
| 256 |
|
|
| 257 |
if (!data) data = createTestAudio(channels, _step, count); |
|
| 258 |
for (size_t i = 0; i < count; ++i) {
|
|
| 259 |
#ifdef __GNUC__ |
|
| 260 |
float *ptr[channels]; |
|
| 261 |
#else |
|
| 262 |
float **ptr = (float **)alloca(channels * sizeof(float)); |
|
| 263 |
#endif |
|
| 264 |
size_t idx = i * _step; |
|
| 265 |
for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx; |
|
| 266 |
RealTime timestamp = RealTime::frame2RealTime(idx, rate); |
|
| 267 |
Plugin::FeatureSet fs = p->process(ptr, timestamp); |
|
| 268 |
appendFeatures(f[run], fs); |
|
| 269 |
} |
|
| 270 |
Plugin::FeatureSet fs = p->getRemainingFeatures(); |
|
| 271 |
appendFeatures(f[run], fs); |
|
| 272 |
} |
|
| 273 |
if (data) destroyTestAudio(data, channels); |
|
| 274 |
|
|
| 275 |
if (!(f[0] == f[1])) {
|
|
| 276 |
string message = "Call to reset after setting parameters, but before processing, changes the results (parameter values not retained through reset?)"; |
|
| 277 |
Result res; |
|
| 278 |
if (options & NonDeterministic) res = note(message); |
|
| 279 |
else res = error(message); |
|
| 280 |
if (options & Verbose) dumpDiff(res, f[0], f[1]); |
|
| 281 |
r.push_back(res); |
|
| 282 |
} else {
|
|
| 283 |
r.push_back(success()); |
|
| 284 |
} |
|
| 285 |
|
|
| 286 |
return r; |
|
| 287 |
} |
|
| TestDefaults.h | ||
|---|---|---|
| 1 |
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
|
| 2 |
|
|
| 3 |
/* |
|
| 4 |
Vamp Plugin Tester |
|
| 5 |
Chris Cannam, cannam@all-day-breakfast.com |
|
| 6 |
Centre for Digital Music, Queen Mary, University of London. |
|
| 7 |
Copyright 2009-2014 QMUL. |
|
| 8 |
|
|
| 9 |
This program loads a Vamp plugin and tests its susceptibility to a |
|
| 10 |
number of common pitfalls, including handling of extremes of input |
|
| 11 |
data. If you can think of any additional useful tests that are |
|
| 12 |
easily added, please send them to me. |
|
| 13 |
|
|
| 14 |
Permission is hereby granted, free of charge, to any person |
|
| 15 |
obtaining a copy of this software and associated documentation |
|
| 16 |
files (the "Software"), to deal in the Software without |
|
| 17 |
restriction, including without limitation the rights to use, copy, |
|
| 18 |
modify, merge, publish, distribute, sublicense, and/or sell copies |
|
| 19 |
of the Software, and to permit persons to whom the Software is |
|
| 20 |
furnished to do so, subject to the following conditions: |
|
| 21 |
|
|
| 22 |
The above copyright notice and this permission notice shall be |
|
| 23 |
included in all copies or substantial portions of the Software. |
|
| 24 |
|
|
| 25 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
| 26 |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
| 27 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
| 28 |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR |
|
| 29 |
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
|
| 30 |
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
| 31 |
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
| 32 |
|
|
| 33 |
Except as contained in this notice, the names of the Centre for |
|
| 34 |
Digital Music; Queen Mary, University of London; and Chris Cannam |
|
| 35 |
shall not be used in advertising or otherwise to promote the sale, |
|
| 36 |
use or other dealings in this Software without prior written |
|
| 37 |
authorization. |
|
| 38 |
*/ |
|
| 39 |
|
|
| 40 |
#ifndef _TEST_DEFAULTS_H_ |
|
| 41 |
#define _TEST_DEFAULTS_H_ |
|
| 42 |
|
|
| 43 |
#include "Test.h" |
|
| 44 |
#include "Tester.h" |
|
| 45 |
|
|
| 46 |
class TestDefaultProgram : public Test |
|
| 47 |
{
|
|
| 48 |
public: |
|
| 49 |
TestDefaultProgram() : Test() { }
|
|
| 50 |
Results test(std::string key, Options options); |
|
| 51 |
|
|
| 52 |
protected: |
|
| 53 |
static Tester::TestRegistrar<TestDefaultProgram> m_registrar; |
|
| 54 |
}; |
|
| 55 |
|
|
| 56 |
class TestDefaultParameters : public Test |
|
| 57 |
{
|
|
| 58 |
public: |
|
| 59 |
TestDefaultParameters() : Test() { }
|
|
| 60 |
Results test(std::string key, Options options); |
|
| 61 |
|
|
| 62 |
protected: |
|
| 63 |
static Tester::TestRegistrar<TestDefaultParameters> m_registrar; |
|
| 64 |
}; |
|
| 65 |
|
|
| 66 |
class TestParametersOnReset : public Test |
|
| 67 |
{
|
|
| 68 |
public: |
|
| 69 |
TestParametersOnReset() : Test() { }
|
|
| 70 |
Results test(std::string key, Options options); |
|
| 71 |
|
|
| 72 |
protected: |
|
| 73 |
static Tester::TestRegistrar<TestParametersOnReset> m_registrar; |
|
| 74 |
}; |
|
| 75 |
|
|
| 76 |
#endif |
|
| TestInitialise.cpp | ||
|---|---|---|
| 1 |
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
|
| 2 |
|
|
| 3 |
/* |
|
| 4 |
Vamp Plugin Tester |
|
| 5 |
Chris Cannam, cannam@all-day-breakfast.com |
|
| 6 |
Centre for Digital Music, Queen Mary, University of London. |
|
| 7 |
Copyright 2009-2014 QMUL. |
|
| 8 |
|
|
| 9 |
This program loads a Vamp plugin and tests its susceptibility to a |
|
| 10 |
number of common pitfalls, including handling of extremes of input |
|
| 11 |
data. If you can think of any additional useful tests that are |
|
| 12 |
easily added, please send them to me. |
|
| 13 |
|
|
| 14 |
Permission is hereby granted, free of charge, to any person |
|
| 15 |
obtaining a copy of this software and associated documentation |
|
| 16 |
files (the "Software"), to deal in the Software without |
|
| 17 |
restriction, including without limitation the rights to use, copy, |
|
| 18 |
modify, merge, publish, distribute, sublicense, and/or sell copies |
|
| 19 |
of the Software, and to permit persons to whom the Software is |
|
| 20 |
furnished to do so, subject to the following conditions: |
|
| 21 |
|
|
| 22 |
The above copyright notice and this permission notice shall be |
|
| 23 |
included in all copies or substantial portions of the Software. |
|
| 24 |
|
|
| 25 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
| 26 |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
| 27 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
| 28 |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR |
|
| 29 |
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
|
| 30 |
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
| 31 |
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
| 32 |
|
|
| 33 |
Except as contained in this notice, the names of the Centre for |
|
| 34 |
Digital Music; Queen Mary, University of London; and Chris Cannam |
|
| 35 |
shall not be used in advertising or otherwise to promote the sale, |
|
| 36 |
use or other dealings in this Software without prior written |
|
| 37 |
authorization. |
|
| 38 |
*/ |
|
| 39 |
|
|
| 40 |
#include "TestInitialise.h" |
|
| 41 |
|
|
| 42 |
#include <vamp-hostsdk/Plugin.h> |
|
| 43 |
#include <vamp-hostsdk/PluginLoader.h> |
|
| 44 |
using namespace Vamp; |
|
| 45 |
using namespace Vamp::HostExt; |
|
| 46 |
|
|
| 47 |
#include <set> |
|
| 48 |
#include <memory> |
|
| 49 |
using namespace std; |
|
| 50 |
|
|
| 51 |
#include <cmath> |
|
| 52 |
#include <ctime> |
|
| 53 |
|
|
| 54 |
#ifndef __GNUC__ |
|
| 55 |
#include <alloca.h> |
|
| 56 |
#endif |
|
| 57 |
|
|
| 58 |
Tester::TestRegistrar<TestSampleRates> |
|
| 59 |
TestSampleRates::m_registrar("F1", "Different sample rates");
|
|
| 60 |
|
|
| 61 |
Tester::TestRegistrar<TestLengthyConstructor> |
|
| 62 |
TestLengthyConstructor::m_registrar("F2", "Lengthy constructor");
|
|
| 63 |
|
|
| 64 |
Test::Results |
|
| 65 |
TestSampleRates::test(string key, Options options) |
|
| 66 |
{
|
|
| 67 |
int rates[] = |
|
| 68 |
{ 111, 800, 10099, 11024, 44100, 48000, 96000, 192000, 201011, 1094091 };
|
|
| 69 |
|
|
| 70 |
Results r; |
|
| 71 |
|
|
| 72 |
if (options & Verbose) {
|
|
| 73 |
cout << " "; |
|
| 74 |
} |
|
| 75 |
|
|
| 76 |
for (int i = 0; i < int(sizeof(rates)/sizeof(rates[0])); ++i) {
|
|
| 77 |
|
|
| 78 |
int rate = rates[i]; |
|
| 79 |
|
|
| 80 |
if (options & Verbose) {
|
|
| 81 |
cout << "[" << rate << "Hz] " << flush; |
|
| 82 |
} |
|
| 83 |
|
|
| 84 |
auto_ptr<Plugin> p(load(key, rate)); |
|
| 85 |
Plugin::FeatureSet f; |
|
| 86 |
float **data = 0; |
|
| 87 |
size_t channels = 0; |
|
| 88 |
|
|
| 89 |
// Aim to feed the plugin a roughly fixed input duration in secs |
|
| 90 |
const float seconds = 10.f; |
|
| 91 |
size_t step = 1000; |
|
| 92 |
size_t count = (seconds * rate) / step; |
|
| 93 |
if (count < 1) count = 1; |
|
| 94 |
|
|
| 95 |
Results subr; |
|
| 96 |
if (!initAdapted(p.get(), channels, step, step, subr)) {
|
|
| 97 |
// This is not an error; the plugin can legitimately |
|
| 98 |
// refuse to initialise at weird settings and that's often |
|
| 99 |
// the most acceptable result |
|
| 100 |
if (!subr.empty()) {
|
|
| 101 |
r.push_back(note(subr.begin()->message())); |
|
| 102 |
} |
|
| 103 |
continue; |
|
| 104 |
} |
|
| 105 |
|
|
| 106 |
data = createTestAudio(channels, step, count); |
|
| 107 |
for (size_t j = 0; j < count; ++j) {
|
|
| 108 |
#ifdef __GNUC__ |
|
| 109 |
float *ptr[channels]; |
|
| 110 |
#else |
|
| 111 |
float **ptr = (float **)alloca(channels * sizeof(float)); |
|
| 112 |
#endif |
|
| 113 |
size_t idx = j * step; |
|
| 114 |
for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx; |
|
| 115 |
RealTime timestamp = RealTime::frame2RealTime(idx, rate); |
|
| 116 |
Plugin::FeatureSet fs = p->process(ptr, timestamp); |
|
| 117 |
appendFeatures(f, fs); |
|
| 118 |
} |
|
| 119 |
Plugin::FeatureSet fs = p->getRemainingFeatures(); |
|
| 120 |
appendFeatures(f, fs); |
|
| 121 |
destroyTestAudio(data, channels); |
|
| 122 |
} |
|
| 123 |
|
|
| 124 |
if (options & Verbose) cout << endl; |
|
| 125 |
|
|
| 126 |
// We can't actually do anything meaningful with our results. |
|
| 127 |
// We're really just testing to see whether the plugin crashes. I |
|
| 128 |
// wonder whether it's possible to do any better? If not, we |
|
| 129 |
// should probably report our limitations |
|
| 130 |
|
|
| 131 |
return r; |
|
| 132 |
} |
|
| 133 |
|
|
| 134 |
Test::Results |
|
| 135 |
TestLengthyConstructor::test(string key, Options) |
|
| 136 |
{
|
|
| 137 |
time_t t0 = time(0); |
|
| 138 |
auto_ptr<Plugin> p(load(key)); |
|
| 139 |
time_t t1 = time(0); |
|
| 140 |
Results r; |
|
| 141 |
if (t1 - t0 > 1) r.push_back(warning("Constructor takes some time to run: work should be deferred to initialise?"));
|
|
| 142 |
return r; |
|
| 143 |
} |
|
| 144 |
|
|
| TestInitialise.h | ||
|---|---|---|
| 1 |
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
|
| 2 |
|
|
| 3 |
/* |
|
| 4 |
Vamp Plugin Tester |
|
| 5 |
Chris Cannam, cannam@all-day-breakfast.com |
|
| 6 |
Centre for Digital Music, Queen Mary, University of London. |
|
| 7 |
Copyright 2009-2014 QMUL. |
|
| 8 |
|
|
| 9 |
This program loads a Vamp plugin and tests its susceptibility to a |
|
| 10 |
number of common pitfalls, including handling of extremes of input |
|
| 11 |
data. If you can think of any additional useful tests that are |
|
| 12 |
easily added, please send them to me. |
|
| 13 |
|
|
| 14 |
Permission is hereby granted, free of charge, to any person |
|
| 15 |
obtaining a copy of this software and associated documentation |
|
| 16 |
files (the "Software"), to deal in the Software without |
|
| 17 |
restriction, including without limitation the rights to use, copy, |
|
| 18 |
modify, merge, publish, distribute, sublicense, and/or sell copies |
|
| 19 |
of the Software, and to permit persons to whom the Software is |
|
| 20 |
furnished to do so, subject to the following conditions: |
|
| 21 |
|
|
| 22 |
The above copyright notice and this permission notice shall be |
|
| 23 |
included in all copies or substantial portions of the Software. |
|
| 24 |
|
|
| 25 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
| 26 |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
| 27 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
| 28 |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR |
|
| 29 |
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
|
| 30 |
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
| 31 |
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
| 32 |
|
|
| 33 |
Except as contained in this notice, the names of the Centre for |
|
| 34 |
Digital Music; Queen Mary, University of London; and Chris Cannam |
|
| 35 |
shall not be used in advertising or otherwise to promote the sale, |
|
| 36 |
use or other dealings in this Software without prior written |
|
| 37 |
authorization. |
|
| 38 |
*/ |
|
| 39 |
|
|
| 40 |
#ifndef _TEST_INITIALISE_H_ |
|
| 41 |
#define _TEST_INITIALISE_H_ |
|
| 42 |
|
|
| 43 |
#include "Test.h" |
|
| 44 |
#include "Tester.h" |
|
| 45 |
|
|
| 46 |
class TestSampleRates : public Test |
|
| 47 |
{
|
|
| 48 |
public: |
|
| 49 |
TestSampleRates() : Test() { }
|
|
| 50 |
Results test(std::string key, Options options); |
|
| 51 |
|
|
| 52 |
protected: |
|
| 53 |
static Tester::TestRegistrar<TestSampleRates> m_registrar; |
|
| 54 |
}; |
|
| 55 |
|
|
| 56 |
class TestLengthyConstructor : public Test |
|
| 57 |
{
|
|
| 58 |
public: |
|
| 59 |
TestLengthyConstructor() : Test() { }
|
|
| 60 |
Results test(std::string key, Options options); |
|
| 61 |
|
|
| 62 |
protected: |
|
| 63 |
static Tester::TestRegistrar<TestLengthyConstructor> m_registrar; |
|
| 64 |
}; |
|
| 65 |
|
|
| 66 |
#endif |
|
| TestInputExtremes.cpp | ||
|---|---|---|
| 1 |
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
|
| 2 |
|
|
| 3 |
/* |
|
| 4 |
Vamp Plugin Tester |
|
| 5 |
Chris Cannam, cannam@all-day-breakfast.com |
|
| 6 |
Centre for Digital Music, Queen Mary, University of London. |
|
| 7 |
Copyright 2009-2014 QMUL. |
|
| 8 |
|
|
| 9 |
This program loads a Vamp plugin and tests its susceptibility to a |
|
| 10 |
number of common pitfalls, including handling of extremes of input |
|
| 11 |
data. If you can think of any additional useful tests that are |
|
| 12 |
easily added, please send them to me. |
|
| 13 |
|
|
| 14 |
Permission is hereby granted, free of charge, to any person |
|
| 15 |
obtaining a copy of this software and associated documentation |
|
| 16 |
files (the "Software"), to deal in the Software without |
|
| 17 |
restriction, including without limitation the rights to use, copy, |
|
| 18 |
modify, merge, publish, distribute, sublicense, and/or sell copies |
|
| 19 |
of the Software, and to permit persons to whom the Software is |
|
| 20 |
furnished to do so, subject to the following conditions: |
|
| 21 |
|
|
| 22 |
The above copyright notice and this permission notice shall be |
|
| 23 |
included in all copies or substantial portions of the Software. |
|
| 24 |
|
|
| 25 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
| 26 |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
| 27 |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
| 28 |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR |
|
| 29 |
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
|
Also available in: Unified diff