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 @ 52:4bd0cd3c60f3

History | View | Annotate | Download (11.3 KB)

1
/* -*- 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
    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 "Test.h"
41

    
42
#include <vamp-hostsdk/PluginLoader.h>
43

    
44
using namespace Vamp;
45
using namespace Vamp::HostExt;
46

    
47
#include <math.h>
48

    
49
#ifdef __SUNPRO_CC
50
#include <ieeefp.h>
51
#define isinf(x) (!finite(x))
52
#endif
53

    
54
Test::Test() { }
55
Test::~Test() { }
56

    
57
using std::cerr;
58
using std::cout;
59
using std::endl;
60
using std::string;
61

    
62
Plugin *
63
Test::load(string key, float rate)
64
{
65
    Plugin *p = PluginLoader::getInstance()->loadPlugin
66
        (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
}
147

    
148
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
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
void
179
Test::dumpFeature(const Plugin::Feature &f, bool showValues)
180
{
181
    cout << "    Timestamp: " << (!f.hasTimestamp ? "(none)" : f.timestamp.toText()) << endl;
182
    cout << "    Duration: " << (!f.hasDuration ? "(none)" : f.duration.toText()) << endl;
183
    cout << "    Label: " << (f.label == "" ? "(none)" : f.label) << endl;
184
    if (showValues) {
185
        cout << "    Values (" << f.values.size() << "): " << (f.values.empty() ? "(none)" : "");
186
        for (int j = 0; j < (int)f.values.size(); ++j) {
187
            cout << f.values[j] << " ";
188
        }
189
        cout << endl;
190
    } else {
191
        cout << "    Values (" << f.values.size() << "): (elided)" << endl;
192
    }
193
}    
194

    
195
void
196
Test::dump(const Plugin::FeatureSet &fs, bool showValues)
197
{
198
    for (Plugin::FeatureSet::const_iterator fsi = fs.begin();
199
         fsi != fs.end(); ++fsi) {
200
        int output = fsi->first;
201
        cout << "Output " << output << ":" << endl;
202
        const Plugin::FeatureList &fl = fsi->second;
203
        for (int i = 0; i < (int)fl.size(); ++i) {
204
            cout << "  Feature " << i << ":" << endl;
205
            const Plugin::Feature &f = fl[i];
206
            dumpFeature(f, showValues);
207
        }
208
    }
209
}
210

    
211
void
212
Test::dumpTwo(const Result &r,
213
              const Plugin::FeatureSet &a,
214
              const Plugin::FeatureSet &b)
215
{
216
    std::cout << r.message() << std::endl;
217
    std::cout << "\nFirst result set:" << std::endl;
218
    dump(a, false);
219
    std::cout << "\nSecond result set:" << std::endl;
220
    dump(b, false);
221
    std::cout << std::endl;
222
}
223

    
224
void
225
Test::dumpDiff(const Result &r,
226
               const Plugin::FeatureSet &a,
227
               const Plugin::FeatureSet &b)
228
{
229
    cout << r.message() << endl;
230
    cout << "\nDifferences follow:" << endl;
231
    if (a.size() != b.size()) {
232
        cout << "*** First result set has features on " << a.size() 
233
                  << " output(s), second has features on " << b.size()
234
                  << endl;
235
        return;
236
    }
237
    Plugin::FeatureSet::const_iterator ai = a.begin();
238
    Plugin::FeatureSet::const_iterator bi = b.begin();
239
    while (ai != a.end()) {
240
        if (ai->first != bi->first) {
241
            cout << "\n*** Output number mismatch: first result set says "
242
                      << ai->first << " where second says " << bi->first
243
                      << endl;
244
        } else {
245
            cout << "\nOutput " << ai->first << ":" << endl;
246
            if (ai->second.size() != bi->second.size()) {
247
                cout << "*** First result set has " << ai->second.size()
248
                          << " feature(s) on this output, second has "
249
                          << bi->second.size() << endl;
250
            } else {
251
                int fno = 0;
252
                int diffcount = 0;
253
                Plugin::FeatureList::const_iterator afi = ai->second.begin();
254
                Plugin::FeatureList::const_iterator bfi = bi->second.begin();
255
                while (afi != ai->second.end()) {
256
                    if (!(*afi == *bfi)) {
257
                        if (diffcount == 0) {
258
                            bool differInValues = (afi->values != bfi->values);
259
                            if (afi->hasTimestamp != bfi->hasTimestamp) {
260
                                cout << "*** Feature " << fno << " differs in presence of timestamp (" << afi->hasTimestamp << " vs " << bfi->hasTimestamp << ")" << endl;
261
                            }
262
                            if (afi->hasTimestamp && (afi->timestamp != bfi->timestamp)) {
263
                                cout << "*** Feature " << fno << " differs in timestamp (" << afi->timestamp << " vs " << bfi->timestamp << " )" << endl;
264
                            }
265
                            if (afi->hasDuration != bfi->hasDuration) {
266
                                cout << "*** Feature " << fno << " differs in presence of duration (" << afi->hasDuration << " vs " << bfi->hasDuration << ")" << endl;
267
                            }
268
                            if (afi->hasDuration && (afi->duration != bfi->duration)) {
269
                                cout << "*** Feature " << fno << " differs in duration (" << afi->duration << " vs " << bfi->duration << " )" << endl;
270
                            }
271
                            if (afi->label != bfi->label) {
272
                                cout << "*** Feature " << fno << " differs in label" << endl;
273
                            }
274
                            if (differInValues) {
275
                                cout << "*** Feature " << fno << " differs in values" << endl;
276
                            }
277
                            cout << "  First output:" << endl;
278
                            dumpFeature(*afi, differInValues);
279
                            cout << "  Second output:" << endl;
280
                            dumpFeature(*bfi, differInValues);
281
                        }
282
                        ++diffcount;
283
                    }
284
                    ++fno;
285
                    ++afi;
286
                    ++bfi;
287
                }
288
                if (diffcount > 1) {
289
                    cout << diffcount-1 << " subsequent differing feature(s) elided" << endl;
290
                }
291
            }
292
        }                
293
        ++ai;
294
        ++bi;
295
    }
296
    cout << endl;
297
}
298

    
299
bool
300
operator==(const Plugin::FeatureSet &a, const Plugin::FeatureSet &b)
301
{
302
    if (a.size() != b.size()) return false;
303
    for (Plugin::FeatureSet::const_iterator ai = a.begin();
304
         ai != a.end(); ++ai) {
305
        int output = ai->first;
306
        Plugin::FeatureSet::const_iterator bi = b.find(output);
307
        if (bi == b.end()) return false;
308
        if (!(ai->second == bi->second)) return false;
309
    }
310
    return true;
311
}
312

    
313
bool
314
operator==(const Plugin::FeatureList &a, const Plugin::FeatureList &b)
315
{
316
    if (a.size() != b.size()) return false;
317
    for (int i = 0; i < (int)a.size(); ++i) {
318
        if (!(a[i] == b[i])) return false;
319
    }
320
    return true;
321
}
322

    
323
bool
324
operator==(const Plugin::Feature &a, const Plugin::Feature &b)
325
{
326
    if (a.hasTimestamp != b.hasTimestamp) return false;
327
    if (a.hasTimestamp && (a.timestamp != b.timestamp)) return false;
328
    if (a.hasDuration != b.hasDuration) return false;
329
    if (a.hasDuration && (a.duration != b.duration)) return false;
330
    if (a.values != b.values) return false;
331
    if (a.label != b.label) return false;
332
    return true;
333
}
334