annotate TestMultipleRuns.cpp @ 26:eff1772ba397 vamp-plugin-tester-v1.0-erroneous

* More doc corrections to match error reporting updates in SDK * Don't return success after failing to load a plugin!
author cannam
date Tue, 22 Sep 2009 11:24:31 +0000
parents df121992f23a
children b1bc4d045a4b
rev   line source
cannam@2 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@2 2
cannam@2 3 /*
cannam@2 4 Vamp Plugin Tester
cannam@2 5 Chris Cannam, cannam@all-day-breakfast.com
cannam@2 6 Centre for Digital Music, Queen Mary, University of London.
cannam@2 7 Copyright 2009 QMUL.
cannam@2 8
cannam@2 9 This program loads a Vamp plugin and tests its susceptibility to a
cannam@2 10 number of common pitfalls, including handling of extremes of input
cannam@2 11 data. If you can think of any additional useful tests that are
cannam@2 12 easily added, please send them to me.
cannam@2 13
cannam@2 14 Permission is hereby granted, free of charge, to any person
cannam@2 15 obtaining a copy of this software and associated documentation
cannam@2 16 files (the "Software"), to deal in the Software without
cannam@2 17 restriction, including without limitation the rights to use, copy,
cannam@2 18 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@2 19 of the Software, and to permit persons to whom the Software is
cannam@2 20 furnished to do so, subject to the following conditions:
cannam@2 21
cannam@2 22 The above copyright notice and this permission notice shall be
cannam@2 23 included in all copies or substantial portions of the Software.
cannam@2 24
cannam@2 25 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@2 26 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@2 27 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@2 28 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@2 29 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@2 30 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@2 31 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@2 32
cannam@2 33 Except as contained in this notice, the names of the Centre for
cannam@2 34 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@2 35 shall not be used in advertising or otherwise to promote the sale,
cannam@2 36 use or other dealings in this Software without prior written
cannam@2 37 authorization.
cannam@2 38 */
cannam@2 39
cannam@2 40 #include "TestMultipleRuns.h"
cannam@2 41
cannam@2 42 #include <vamp-hostsdk/Plugin.h>
cannam@2 43 using namespace Vamp;
cannam@2 44
cannam@2 45 #include <memory>
cannam@2 46 using namespace std;
cannam@2 47
cannam@2 48 #include <cmath>
cannam@2 49
cannam@2 50 Tester::TestRegistrar<TestDistinctRuns>
cannam@4 51 TestDistinctRuns::m_registrar("D1 Consecutive runs with separate instances");
cannam@2 52
cannam@2 53 Tester::TestRegistrar<TestReset>
cannam@4 54 TestReset::m_registrar("D2 Consecutive runs with a single instance using reset");
cannam@2 55
cannam@2 56 Tester::TestRegistrar<TestInterleavedRuns>
cannam@4 57 TestInterleavedRuns::m_registrar("D3 Simultaneous interleaved runs in a single thread");
cannam@2 58
cannam@5 59 Tester::TestRegistrar<TestDifferentStartTimes>
cannam@5 60 TestDifferentStartTimes::m_registrar("D4 Consecutive runs with different start times");
cannam@5 61
cannam@3 62 static const size_t _step = 1000;
cannam@3 63
cannam@2 64 Test::Results
cannam@8 65 TestDistinctRuns::test(string key, Options options)
cannam@2 66 {
cannam@2 67 Plugin::FeatureSet f[2];
cannam@2 68 int rate = 44100;
cannam@2 69 Results r;
cannam@3 70 float **data = 0;
cannam@3 71 size_t channels = 0;
cannam@3 72 size_t count = 100;
cannam@2 73
cannam@2 74 for (int run = 0; run < 2; ++run) {
cannam@2 75 auto_ptr<Plugin> p(load(key, rate));
cannam@3 76 if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
cannam@3 77 if (!data) data = createTestAudio(channels, _step, count);
cannam@3 78 for (size_t i = 0; i < count; ++i) {
cannam@3 79 float *ptr[channels];
cannam@3 80 size_t idx = i * _step;
cannam@3 81 for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
cannam@2 82 RealTime timestamp = RealTime::frame2RealTime(idx, rate);
cannam@3 83 Plugin::FeatureSet fs = p->process(ptr, timestamp);
cannam@2 84 appendFeatures(f[run], fs);
cannam@2 85 }
cannam@2 86 Plugin::FeatureSet fs = p->getRemainingFeatures();
cannam@2 87 appendFeatures(f[run], fs);
cannam@2 88 }
cannam@3 89 if (data) destroyTestAudio(data, channels);
cannam@2 90
cannam@2 91 if (!(f[0] == f[1])) {
cannam@8 92 Result res;
cannam@8 93 string message = "Consecutive runs with separate instances produce different results";
cannam@8 94 if (options & NonDeterministic) res = note(message);
cannam@8 95 else res = error(message);
cannam@8 96 if (options & Verbose) dump(res, f[0], f[1]);
cannam@7 97 r.push_back(res);
cannam@2 98 } else {
cannam@2 99 r.push_back(success());
cannam@2 100 }
cannam@2 101
cannam@2 102 return r;
cannam@2 103 }
cannam@2 104
cannam@2 105 Test::Results
cannam@8 106 TestReset::test(string key, Options options)
cannam@2 107 {
cannam@2 108 Plugin::FeatureSet f[2];
cannam@2 109 int rate = 44100;
cannam@2 110 Results r;
cannam@3 111 float **data = 0;
cannam@3 112 size_t channels = 0;
cannam@3 113 size_t count = 100;
cannam@2 114
cannam@2 115 auto_ptr<Plugin> p(load(key, rate));
cannam@3 116
cannam@2 117 for (int run = 0; run < 2; ++run) {
cannam@2 118 if (run == 1) p->reset();
cannam@11 119 else if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
cannam@3 120 if (!data) data = createTestAudio(channels, _step, count);
cannam@3 121 for (size_t i = 0; i < count; ++i) {
cannam@3 122 float *ptr[channels];
cannam@3 123 size_t idx = i * _step;
cannam@3 124 for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
cannam@2 125 RealTime timestamp = RealTime::frame2RealTime(idx, rate);
cannam@3 126 Plugin::FeatureSet fs = p->process(ptr, timestamp);
cannam@2 127 appendFeatures(f[run], fs);
cannam@2 128 }
cannam@2 129 Plugin::FeatureSet fs = p->getRemainingFeatures();
cannam@2 130 appendFeatures(f[run], fs);
cannam@2 131 }
cannam@3 132 if (data) destroyTestAudio(data, channels);
cannam@2 133
cannam@2 134 if (!(f[0] == f[1])) {
cannam@8 135 string message = "Consecutive runs with the same instance (using reset) produce different results";
cannam@8 136 Result res;
cannam@8 137 if (options & NonDeterministic) res = note(message);
cannam@8 138 else res = error(message);
cannam@8 139 if (options & Verbose) dump(res, f[0], f[1]);
cannam@3 140 r.push_back(res);
cannam@2 141 } else {
cannam@2 142 r.push_back(success());
cannam@2 143 }
cannam@2 144
cannam@2 145 return r;
cannam@2 146 }
cannam@2 147
cannam@2 148 Test::Results
cannam@8 149 TestInterleavedRuns::test(string key, Options options)
cannam@2 150 {
cannam@2 151 Plugin::FeatureSet f[2];
cannam@2 152 int rate = 44100;
cannam@2 153 Results r;
cannam@3 154 float **data = 0;
cannam@3 155 size_t channels = 0;
cannam@3 156 size_t count = 100;
cannam@3 157
cannam@2 158 Plugin *p[2];
cannam@2 159 for (int run = 0; run < 2; ++run) {
cannam@2 160 p[run] = load(key, rate);
cannam@3 161 if (!initAdapted(p[run], channels, _step, _step, r)) {
cannam@2 162 delete p[run];
cannam@2 163 if (run > 0) delete p[0];
cannam@2 164 return r;
cannam@2 165 }
cannam@3 166 if (!data) data = createTestAudio(channels, _step, count);
cannam@2 167 }
cannam@3 168 for (size_t i = 0; i < count; ++i) {
cannam@3 169 float *ptr[channels];
cannam@3 170 size_t idx = i * _step;
cannam@3 171 for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
cannam@2 172 RealTime timestamp = RealTime::frame2RealTime(idx, rate);
cannam@2 173 for (int run = 0; run < 2; ++run) {
cannam@3 174 Plugin::FeatureSet fs = p[run]->process(ptr, timestamp);
cannam@2 175 appendFeatures(f[run], fs);
cannam@2 176 }
cannam@2 177 }
cannam@2 178 for (int run = 0; run < 2; ++run) {
cannam@2 179 Plugin::FeatureSet fs = p[run]->getRemainingFeatures();
cannam@2 180 appendFeatures(f[run], fs);
cannam@2 181 delete p[run];
cannam@2 182 }
cannam@2 183
cannam@3 184 if (data) destroyTestAudio(data, channels);
cannam@2 185
cannam@2 186 if (!(f[0] == f[1])) {
cannam@8 187 string message = "Simultaneous runs with separate instances produce different results";
cannam@8 188 Result res;
cannam@8 189 if (options & NonDeterministic) res = note(message);
cannam@8 190 else res = error(message);
cannam@8 191 if (options & Verbose) dump(res, f[0], f[1]);
cannam@7 192 r.push_back(res);
cannam@2 193 } else {
cannam@2 194 r.push_back(success());
cannam@2 195 }
cannam@2 196
cannam@2 197 return r;
cannam@2 198 }
cannam@5 199
cannam@5 200 Test::Results
cannam@8 201 TestDifferentStartTimes::test(string key, Options options)
cannam@5 202 {
cannam@5 203 Plugin::FeatureSet f[2];
cannam@5 204 int rate = 44100;
cannam@5 205 Results r;
cannam@5 206 float **data = 0;
cannam@5 207 size_t channels = 0;
cannam@5 208 size_t count = 100;
cannam@5 209
cannam@5 210 for (int run = 0; run < 2; ++run) {
cannam@5 211 auto_ptr<Plugin> p(load(key, rate));
cannam@5 212 if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
cannam@5 213 if (!data) data = createTestAudio(channels, _step, count);
cannam@5 214 for (size_t i = 0; i < count; ++i) {
cannam@5 215 float *ptr[channels];
cannam@5 216 size_t idx = i * _step;
cannam@5 217 for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
cannam@5 218 RealTime timestamp = RealTime::frame2RealTime(idx, rate);
cannam@5 219 if (run == 1) timestamp = timestamp + RealTime::fromSeconds(10);
cannam@5 220 Plugin::FeatureSet fs = p->process(ptr, timestamp);
cannam@5 221 appendFeatures(f[run], fs);
cannam@5 222 }
cannam@5 223 Plugin::FeatureSet fs = p->getRemainingFeatures();
cannam@5 224 appendFeatures(f[run], fs);
cannam@5 225 }
cannam@5 226 if (data) destroyTestAudio(data, channels);
cannam@5 227
cannam@5 228 if (f[0] == f[1]) {
cannam@8 229 string message = "Consecutive runs with different starting timestamps produce the same result";
cannam@8 230 Result res;
cannam@8 231 if (options & NonDeterministic) res = note(message);
cannam@13 232 else res = warning(message);
cannam@8 233 if (options & Verbose) dump(res, f[0], f[1]);
cannam@7 234 r.push_back(res);
cannam@5 235 } else {
cannam@5 236 r.push_back(success());
cannam@5 237 }
cannam@5 238
cannam@5 239 return r;
cannam@5 240 }