annotate TestMultipleRuns.cpp @ 28:b1bc4d045a4b vamp-plugin-tester-v1.0

* Solaris build fixes
author cannam
date Thu, 24 Sep 2009 14:11:14 +0000
parents df121992f23a
children 07144cdcbedf
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@28 50 #ifndef __GNUC__
cannam@28 51 #include <alloca.h>
cannam@28 52 #endif
cannam@28 53
cannam@2 54 Tester::TestRegistrar<TestDistinctRuns>
cannam@4 55 TestDistinctRuns::m_registrar("D1 Consecutive runs with separate instances");
cannam@2 56
cannam@2 57 Tester::TestRegistrar<TestReset>
cannam@4 58 TestReset::m_registrar("D2 Consecutive runs with a single instance using reset");
cannam@2 59
cannam@2 60 Tester::TestRegistrar<TestInterleavedRuns>
cannam@4 61 TestInterleavedRuns::m_registrar("D3 Simultaneous interleaved runs in a single thread");
cannam@2 62
cannam@5 63 Tester::TestRegistrar<TestDifferentStartTimes>
cannam@5 64 TestDifferentStartTimes::m_registrar("D4 Consecutive runs with different start times");
cannam@5 65
cannam@3 66 static const size_t _step = 1000;
cannam@3 67
cannam@2 68 Test::Results
cannam@8 69 TestDistinctRuns::test(string key, Options options)
cannam@2 70 {
cannam@2 71 Plugin::FeatureSet f[2];
cannam@2 72 int rate = 44100;
cannam@2 73 Results r;
cannam@3 74 float **data = 0;
cannam@3 75 size_t channels = 0;
cannam@3 76 size_t count = 100;
cannam@2 77
cannam@2 78 for (int run = 0; run < 2; ++run) {
cannam@2 79 auto_ptr<Plugin> p(load(key, rate));
cannam@3 80 if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
cannam@3 81 if (!data) data = createTestAudio(channels, _step, count);
cannam@3 82 for (size_t i = 0; i < count; ++i) {
cannam@28 83 #ifdef __GNUC__
cannam@3 84 float *ptr[channels];
cannam@28 85 #else
cannam@28 86 float **ptr = (float **)alloca(channels * sizeof(float));
cannam@28 87 #endif
cannam@3 88 size_t idx = i * _step;
cannam@3 89 for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
cannam@2 90 RealTime timestamp = RealTime::frame2RealTime(idx, rate);
cannam@3 91 Plugin::FeatureSet fs = p->process(ptr, timestamp);
cannam@2 92 appendFeatures(f[run], fs);
cannam@2 93 }
cannam@2 94 Plugin::FeatureSet fs = p->getRemainingFeatures();
cannam@2 95 appendFeatures(f[run], fs);
cannam@2 96 }
cannam@3 97 if (data) destroyTestAudio(data, channels);
cannam@2 98
cannam@2 99 if (!(f[0] == f[1])) {
cannam@8 100 Result res;
cannam@8 101 string message = "Consecutive runs with separate instances produce different results";
cannam@8 102 if (options & NonDeterministic) res = note(message);
cannam@8 103 else res = error(message);
cannam@8 104 if (options & Verbose) dump(res, f[0], f[1]);
cannam@7 105 r.push_back(res);
cannam@2 106 } else {
cannam@2 107 r.push_back(success());
cannam@2 108 }
cannam@2 109
cannam@2 110 return r;
cannam@2 111 }
cannam@2 112
cannam@2 113 Test::Results
cannam@8 114 TestReset::test(string key, Options options)
cannam@2 115 {
cannam@2 116 Plugin::FeatureSet f[2];
cannam@2 117 int rate = 44100;
cannam@2 118 Results r;
cannam@3 119 float **data = 0;
cannam@3 120 size_t channels = 0;
cannam@3 121 size_t count = 100;
cannam@2 122
cannam@2 123 auto_ptr<Plugin> p(load(key, rate));
cannam@3 124
cannam@2 125 for (int run = 0; run < 2; ++run) {
cannam@2 126 if (run == 1) p->reset();
cannam@11 127 else if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
cannam@3 128 if (!data) data = createTestAudio(channels, _step, count);
cannam@3 129 for (size_t i = 0; i < count; ++i) {
cannam@28 130 #ifdef __GNUC__
cannam@3 131 float *ptr[channels];
cannam@28 132 #else
cannam@28 133 float **ptr = (float **)alloca(channels * sizeof(float));
cannam@28 134 #endif
cannam@3 135 size_t idx = i * _step;
cannam@3 136 for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
cannam@2 137 RealTime timestamp = RealTime::frame2RealTime(idx, rate);
cannam@3 138 Plugin::FeatureSet fs = p->process(ptr, timestamp);
cannam@2 139 appendFeatures(f[run], fs);
cannam@2 140 }
cannam@2 141 Plugin::FeatureSet fs = p->getRemainingFeatures();
cannam@2 142 appendFeatures(f[run], fs);
cannam@2 143 }
cannam@3 144 if (data) destroyTestAudio(data, channels);
cannam@2 145
cannam@2 146 if (!(f[0] == f[1])) {
cannam@8 147 string message = "Consecutive runs with the same instance (using reset) produce different results";
cannam@8 148 Result res;
cannam@8 149 if (options & NonDeterministic) res = note(message);
cannam@8 150 else res = error(message);
cannam@8 151 if (options & Verbose) dump(res, f[0], f[1]);
cannam@3 152 r.push_back(res);
cannam@2 153 } else {
cannam@2 154 r.push_back(success());
cannam@2 155 }
cannam@2 156
cannam@2 157 return r;
cannam@2 158 }
cannam@2 159
cannam@2 160 Test::Results
cannam@8 161 TestInterleavedRuns::test(string key, Options options)
cannam@2 162 {
cannam@2 163 Plugin::FeatureSet f[2];
cannam@2 164 int rate = 44100;
cannam@2 165 Results r;
cannam@3 166 float **data = 0;
cannam@3 167 size_t channels = 0;
cannam@3 168 size_t count = 100;
cannam@3 169
cannam@2 170 Plugin *p[2];
cannam@2 171 for (int run = 0; run < 2; ++run) {
cannam@2 172 p[run] = load(key, rate);
cannam@3 173 if (!initAdapted(p[run], channels, _step, _step, r)) {
cannam@2 174 delete p[run];
cannam@2 175 if (run > 0) delete p[0];
cannam@2 176 return r;
cannam@2 177 }
cannam@3 178 if (!data) data = createTestAudio(channels, _step, count);
cannam@2 179 }
cannam@3 180 for (size_t i = 0; i < count; ++i) {
cannam@28 181 #ifdef __GNUC__
cannam@3 182 float *ptr[channels];
cannam@28 183 #else
cannam@28 184 float **ptr = (float **)alloca(channels * sizeof(float));
cannam@28 185 #endif
cannam@3 186 size_t idx = i * _step;
cannam@3 187 for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
cannam@2 188 RealTime timestamp = RealTime::frame2RealTime(idx, rate);
cannam@2 189 for (int run = 0; run < 2; ++run) {
cannam@3 190 Plugin::FeatureSet fs = p[run]->process(ptr, timestamp);
cannam@2 191 appendFeatures(f[run], fs);
cannam@2 192 }
cannam@2 193 }
cannam@2 194 for (int run = 0; run < 2; ++run) {
cannam@2 195 Plugin::FeatureSet fs = p[run]->getRemainingFeatures();
cannam@2 196 appendFeatures(f[run], fs);
cannam@2 197 delete p[run];
cannam@2 198 }
cannam@2 199
cannam@3 200 if (data) destroyTestAudio(data, channels);
cannam@2 201
cannam@2 202 if (!(f[0] == f[1])) {
cannam@8 203 string message = "Simultaneous runs with separate instances produce different results";
cannam@8 204 Result res;
cannam@8 205 if (options & NonDeterministic) res = note(message);
cannam@8 206 else res = error(message);
cannam@8 207 if (options & Verbose) dump(res, f[0], f[1]);
cannam@7 208 r.push_back(res);
cannam@2 209 } else {
cannam@2 210 r.push_back(success());
cannam@2 211 }
cannam@2 212
cannam@2 213 return r;
cannam@2 214 }
cannam@5 215
cannam@5 216 Test::Results
cannam@8 217 TestDifferentStartTimes::test(string key, Options options)
cannam@5 218 {
cannam@5 219 Plugin::FeatureSet f[2];
cannam@5 220 int rate = 44100;
cannam@5 221 Results r;
cannam@5 222 float **data = 0;
cannam@5 223 size_t channels = 0;
cannam@5 224 size_t count = 100;
cannam@5 225
cannam@5 226 for (int run = 0; run < 2; ++run) {
cannam@5 227 auto_ptr<Plugin> p(load(key, rate));
cannam@5 228 if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
cannam@5 229 if (!data) data = createTestAudio(channels, _step, count);
cannam@5 230 for (size_t i = 0; i < count; ++i) {
cannam@28 231 #ifdef __GNUC__
cannam@5 232 float *ptr[channels];
cannam@28 233 #else
cannam@28 234 float **ptr = (float **)alloca(channels * sizeof(float));
cannam@28 235 #endif
cannam@5 236 size_t idx = i * _step;
cannam@5 237 for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
cannam@5 238 RealTime timestamp = RealTime::frame2RealTime(idx, rate);
cannam@5 239 if (run == 1) timestamp = timestamp + RealTime::fromSeconds(10);
cannam@5 240 Plugin::FeatureSet fs = p->process(ptr, timestamp);
cannam@5 241 appendFeatures(f[run], fs);
cannam@5 242 }
cannam@5 243 Plugin::FeatureSet fs = p->getRemainingFeatures();
cannam@5 244 appendFeatures(f[run], fs);
cannam@5 245 }
cannam@5 246 if (data) destroyTestAudio(data, channels);
cannam@5 247
cannam@5 248 if (f[0] == f[1]) {
cannam@8 249 string message = "Consecutive runs with different starting timestamps produce the same result";
cannam@8 250 Result res;
cannam@8 251 if (options & NonDeterministic) res = note(message);
cannam@13 252 else res = warning(message);
cannam@8 253 if (options & Verbose) dump(res, f[0], f[1]);
cannam@7 254 r.push_back(res);
cannam@5 255 } else {
cannam@5 256 r.push_back(success());
cannam@5 257 }
cannam@5 258
cannam@5 259 return r;
cannam@5 260 }