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 / TestMultipleRuns.cpp @ 53:86d8a699dfbe

History | View | Annotate | Download (8.89 KB)

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 "TestMultipleRuns.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

    
50
#ifndef __GNUC__
51
#include <alloca.h>
52
#endif
53

    
54
Tester::TestRegistrar<TestDistinctRuns>
55
TestDistinctRuns::m_registrar("D1", "Consecutive runs with separate instances");
56

    
57
Tester::TestRegistrar<TestReset>
58
TestReset::m_registrar("D2", "Consecutive runs with a single instance using reset");
59

    
60
Tester::TestRegistrar<TestInterleavedRuns>
61
TestInterleavedRuns::m_registrar("D3", "Simultaneous interleaved runs in a single thread");
62

    
63
Tester::TestRegistrar<TestDifferentStartTimes>
64
TestDifferentStartTimes::m_registrar("D4", "Consecutive runs with different start times");
65

    
66
static const size_t _step = 1000;
67

    
68
Test::Results
69
TestDistinctRuns::test(string key, Options options)
70
{
71
    Plugin::FeatureSet f[2];
72
    int rate = 44100;
73
    Results r;
74
    float **data = 0;
75
    size_t channels = 0;
76
    size_t count = 100;
77

    
78
    for (int run = 0; run < 2; ++run) {
79
        auto_ptr<Plugin> p(load(key, rate));
80
        if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
81
        if (!data) data = createTestAudio(channels, _step, count);
82
        for (size_t i = 0; i < count; ++i) {
83
#ifdef __GNUC__
84
            float *ptr[channels];
85
#else
86
            float **ptr = (float **)alloca(channels * sizeof(float));
87
#endif
88
            size_t idx = i * _step;
89
            for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
90
            RealTime timestamp = RealTime::frame2RealTime(idx, rate);
91
            Plugin::FeatureSet fs = p->process(ptr, timestamp);
92
            appendFeatures(f[run], fs);
93
        }
94
        Plugin::FeatureSet fs = p->getRemainingFeatures();
95
        appendFeatures(f[run], fs);
96
    }
97
    if (data) destroyTestAudio(data, channels);
98

    
99
    if (!(f[0] == f[1])) {
100
        Result res;
101
        string message = "Consecutive runs with separate instances produce different results";
102
        if (options & NonDeterministic) res = note(message);
103
        else res = error(message);
104
        if (options & Verbose) dumpDiff(res, f[0], f[1]);
105
        r.push_back(res);
106
    } else {
107
        r.push_back(success());
108
    }
109

    
110
    return r;
111
}
112

    
113
Test::Results
114
TestReset::test(string key, Options options)
115
{
116
    Plugin::FeatureSet f[2];
117
    int rate = 44100;
118
    Results r;
119
    float **data = 0;
120
    size_t channels = 0;
121
    size_t count = 100;
122

    
123
    auto_ptr<Plugin> p(load(key, rate));
124

    
125
    for (int run = 0; run < 2; ++run) {
126
        if (run == 1) p->reset();
127
        else if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
128
        if (!data) data = createTestAudio(channels, _step, count);
129
        for (size_t i = 0; i < count; ++i) {
130
#ifdef __GNUC__
131
            float *ptr[channels];
132
#else
133
            float **ptr = (float **)alloca(channels * sizeof(float));
134
#endif
135
            size_t idx = i * _step;
136
            for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
137
            RealTime timestamp = RealTime::frame2RealTime(idx, rate);
138
            Plugin::FeatureSet fs = p->process(ptr, timestamp);
139
            appendFeatures(f[run], fs);
140
        }
141
        Plugin::FeatureSet fs = p->getRemainingFeatures();
142
        appendFeatures(f[run], fs);
143
    }
144
    if (data) destroyTestAudio(data, channels);
145

    
146
    if (!(f[0] == f[1])) {
147
        string message = "Consecutive runs with the same instance (using reset) produce different results";
148
        Result res;
149
        if (options & NonDeterministic) res = note(message);
150
        else res = error(message);
151
        if (options & Verbose) dumpDiff(res, f[0], f[1]);
152
        r.push_back(res);
153
    } else {
154
        r.push_back(success());
155
    }
156

    
157
    return r;
158
}
159

    
160
Test::Results
161
TestInterleavedRuns::test(string key, Options options)
162
{
163
    Plugin::FeatureSet f[2];
164
    int rate = 44100;
165
    Results r;
166
    float **data = 0;
167
    size_t channels = 0;
168
    size_t count = 100;
169

    
170
    Plugin *p[2];
171
    for (int run = 0; run < 2; ++run) {
172
        p[run] = load(key, rate);
173
        if (!initAdapted(p[run], channels, _step, _step, r)) {
174
            delete p[run];
175
            if (run > 0) delete p[0];
176
            return r;
177
        }
178
        if (!data) data = createTestAudio(channels, _step, count);
179
    }
180
    for (size_t i = 0; i < count; ++i) {
181
#ifdef __GNUC__
182
        float *ptr[channels];
183
#else
184
        float **ptr = (float **)alloca(channels * sizeof(float));
185
#endif
186
        size_t idx = i * _step;
187
        for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
188
        RealTime timestamp = RealTime::frame2RealTime(idx, rate);
189
        for (int run = 0; run < 2; ++run) {
190
            Plugin::FeatureSet fs = p[run]->process(ptr, timestamp);
191
            appendFeatures(f[run], fs);
192
        }
193
    }
194
    for (int run = 0; run < 2; ++run) {
195
        Plugin::FeatureSet fs = p[run]->getRemainingFeatures();
196
        appendFeatures(f[run], fs);
197
        delete p[run];
198
    }
199

    
200
    if (data) destroyTestAudio(data, channels);
201

    
202
    if (!(f[0] == f[1])) {
203
        string message = "Simultaneous runs with separate instances produce different results";
204
        Result res;
205
        if (options & NonDeterministic) res = note(message);
206
        else res = error(message);
207
        if (options & Verbose) dumpDiff(res, f[0], f[1]);
208
        r.push_back(res);
209
    } else {
210
        r.push_back(success());
211
    }
212

    
213
    return r;
214
}
215

    
216
Test::Results
217
TestDifferentStartTimes::test(string key, Options options)
218
{
219
    Plugin::FeatureSet f[2];
220
    int rate = 44100;
221
    Results r;
222
    float **data = 0;
223
    size_t channels = 0;
224
    size_t count = 100;
225

    
226
    for (int run = 0; run < 2; ++run) {
227
        auto_ptr<Plugin> p(load(key, rate));
228
        if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
229
        if (!data) data = createTestAudio(channels, _step, count);
230
        for (size_t i = 0; i < count; ++i) {
231
#ifdef __GNUC__
232
            float *ptr[channels];
233
#else
234
            float **ptr = (float **)alloca(channels * sizeof(float));
235
#endif
236
            size_t idx = i * _step;
237
            for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
238
            RealTime timestamp = RealTime::frame2RealTime(idx, rate);
239
            if (run == 1) timestamp = timestamp + RealTime::fromSeconds(10);
240
            Plugin::FeatureSet fs = p->process(ptr, timestamp);
241
            appendFeatures(f[run], fs);
242
        }
243
        Plugin::FeatureSet fs = p->getRemainingFeatures();
244
        appendFeatures(f[run], fs);
245
    }
246
    if (data) destroyTestAudio(data, channels);
247

    
248
    if (f[0] == f[1]) {
249
        Result res;
250
        if (containsTimestamps(f[0])) {
251
            string message = "Consecutive runs with different starting timestamps produce the same result";
252
            if (options & NonDeterministic) {
253
                res = note(message);
254
            } else {
255
                res = warning(message);
256
            }
257
            if (options & Verbose) {
258
                cout << res.message() << endl;
259
                dump(f[0], false);
260
            }
261
        } else {
262
            res = note("Consecutive runs with different starting timestamps produce the same result (but result features contain no timestamps, so this is probably all right)");
263
        }
264
        r.push_back(res);
265
    } else {
266
        r.push_back(success());
267
    }
268

    
269
    return r;
270
}