To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / Test.cpp @ 61:c7fd03f5ae02

History | View | Annotate | Download (13.1 KB)

1 0:f89128a316e7 cannam
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2
3
/*
4
    Vamp Plugin Fuzz Tester
5
    Chris Cannam, cannam@all-day-breakfast.com
6
    Centre for Digital Music, Queen Mary, University of London.
7 42:f1e8e14e9c96 Chris
    Copyright 2009-2014 QMUL.
8 0:f89128a316e7 cannam

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 "Test.h"
41
42
#include <vamp-hostsdk/PluginLoader.h>
43
44
using namespace Vamp;
45
using namespace Vamp::HostExt;
46
47 20:5af5eb2627ad cannam
#include <math.h>
48 1:d7ef749300ed cannam
49 28:b1bc4d045a4b cannam
#ifdef __SUNPRO_CC
50
#include <ieeefp.h>
51
#define isinf(x) (!finite(x))
52
#endif
53
54 0:f89128a316e7 cannam
Test::Test() { }
55
Test::~Test() { }
56
57 52:4bd0cd3c60f3 Chris
using std::cerr;
58
using std::cout;
59
using std::endl;
60
using std::string;
61
62 0:f89128a316e7 cannam
Plugin *
63 52:4bd0cd3c60f3 Chris
Test::load(string key, float rate)
64 0:f89128a316e7 cannam
{
65 23:28097c1b3de4 cannam
    Plugin *p = PluginLoader::getInstance()->loadPlugin
66 0:f89128a316e7 cannam
        (key, rate, PluginLoader::ADAPT_ALL);
67 23:28097c1b3de4 cannam
    if (!p) throw FailedToLoadPlugin();
68
    return p;
69 0:f89128a316e7 cannam
}
70
71 1:d7ef749300ed cannam
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 3:0f65bb22172b cannam
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 1:d7ef749300ed cannam
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 3:0f65bb22172b cannam
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
}
147
148 0:f89128a316e7 cannam
void
149
Test::appendFeatures(Plugin::FeatureSet &a, const Plugin::FeatureSet &b)
150
{
151
    for (Plugin::FeatureSet::const_iterator i = b.begin(); i != b.end(); ++i) {
152
        int output = i->first;
153
        const Plugin::FeatureList &fl = i->second;
154
        Plugin::FeatureList &target = a[output];
155
        for (Plugin::FeatureList::const_iterator j = fl.begin(); j != fl.end(); ++j) {
156
            target.push_back(*j);
157
        }
158
    }
159
}
160
161
bool
162 1:d7ef749300ed cannam
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 53:86d8a699dfbe Chris
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 3:0f65bb22172b cannam
void
195 61:c7fd03f5ae02 Chris
Test::dumpFeature(const Plugin::Feature &f, bool showValues,
196
                  const Plugin::Feature *other)
197 52:4bd0cd3c60f3 Chris
{
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 61:c7fd03f5ae02 Chris
        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 52:4bd0cd3c60f3 Chris
        }
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 3:0f65bb22172b cannam
{
241
    for (Plugin::FeatureSet::const_iterator fsi = fs.begin();
242
         fsi != fs.end(); ++fsi) {
243
        int output = fsi->first;
244 52:4bd0cd3c60f3 Chris
        cout << "Output " << output << ":" << endl;
245 3:0f65bb22172b cannam
        const Plugin::FeatureList &fl = fsi->second;
246
        for (int i = 0; i < (int)fl.size(); ++i) {
247 52:4bd0cd3c60f3 Chris
            cout << "  Feature " << i << ":" << endl;
248 3:0f65bb22172b cannam
            const Plugin::Feature &f = fl[i];
249 52:4bd0cd3c60f3 Chris
            dumpFeature(f, showValues);
250 3:0f65bb22172b cannam
        }
251
    }
252
}
253
254
void
255 52:4bd0cd3c60f3 Chris
Test::dumpTwo(const Result &r,
256
              const Plugin::FeatureSet &a,
257
              const Plugin::FeatureSet &b)
258 3:0f65bb22172b cannam
{
259 8:3019cb6b538d cannam
    std::cout << r.message() << std::endl;
260
    std::cout << "\nFirst result set:" << std::endl;
261 52:4bd0cd3c60f3 Chris
    dump(a, false);
262 8:3019cb6b538d cannam
    std::cout << "\nSecond result set:" << std::endl;
263 52:4bd0cd3c60f3 Chris
    dump(b, false);
264 8:3019cb6b538d cannam
    std::cout << std::endl;
265 3:0f65bb22172b cannam
}
266
267 52:4bd0cd3c60f3 Chris
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 61:c7fd03f5ae02 Chris
                            bool differInValues =
302
                                (afi->values.size() == bfi->values.size() &&
303
                                 afi->values != bfi->values);
304 52:4bd0cd3c60f3 Chris
                            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 61:c7fd03f5ae02 Chris
                            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 52:4bd0cd3c60f3 Chris
                            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 61:c7fd03f5ae02 Chris
                            dumpFeature(*bfi, differInValues, &(*afi));
329 52:4bd0cd3c60f3 Chris
                        }
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 1:d7ef749300ed cannam
bool
348 0:f89128a316e7 cannam
operator==(const Plugin::FeatureSet &a, const Plugin::FeatureSet &b)
349
{
350
    if (a.size() != b.size()) return false;
351
    for (Plugin::FeatureSet::const_iterator ai = a.begin();
352
         ai != a.end(); ++ai) {
353
        int output = ai->first;
354
        Plugin::FeatureSet::const_iterator bi = b.find(output);
355
        if (bi == b.end()) return false;
356
        if (!(ai->second == bi->second)) return false;
357
    }
358
    return true;
359
}
360
361
bool
362
operator==(const Plugin::FeatureList &a, const Plugin::FeatureList &b)
363
{
364
    if (a.size() != b.size()) return false;
365
    for (int i = 0; i < (int)a.size(); ++i) {
366
        if (!(a[i] == b[i])) return false;
367
    }
368
    return true;
369
}
370
371
bool
372
operator==(const Plugin::Feature &a, const Plugin::Feature &b)
373
{
374
    if (a.hasTimestamp != b.hasTimestamp) return false;
375
    if (a.hasTimestamp && (a.timestamp != b.timestamp)) return false;
376
    if (a.hasDuration != b.hasDuration) return false;
377
    if (a.hasDuration && (a.duration != b.duration)) return false;
378
    if (a.values != b.values) return false;
379
    if (a.label != b.label) return false;
380
    return true;
381
}