cannam@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@0: cannam@0: /* cannam@0: Vamp Plugin Tester cannam@0: Chris Cannam, cannam@all-day-breakfast.com cannam@0: Centre for Digital Music, Queen Mary, University of London. Chris@42: Copyright 2009-2014 QMUL. cannam@0: cannam@0: This program loads a Vamp plugin and tests its susceptibility to a cannam@0: number of common pitfalls, including handling of extremes of input cannam@0: data. If you can think of any additional useful tests that are cannam@0: easily added, please send them to me. cannam@0: cannam@0: Permission is hereby granted, free of charge, to any person cannam@0: obtaining a copy of this software and associated documentation cannam@0: files (the "Software"), to deal in the Software without cannam@0: restriction, including without limitation the rights to use, copy, cannam@0: modify, merge, publish, distribute, sublicense, and/or sell copies cannam@0: of the Software, and to permit persons to whom the Software is cannam@0: furnished to do so, subject to the following conditions: cannam@0: cannam@0: The above copyright notice and this permission notice shall be cannam@0: included in all copies or substantial portions of the Software. cannam@0: cannam@0: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, cannam@0: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF cannam@0: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND cannam@0: NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR cannam@0: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF cannam@0: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION cannam@0: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cannam@0: cannam@0: Except as contained in this notice, the names of the Centre for cannam@0: Digital Music; Queen Mary, University of London; and Chris Cannam cannam@0: shall not be used in advertising or otherwise to promote the sale, cannam@0: use or other dealings in this Software without prior written cannam@0: authorization. cannam@0: */ cannam@0: cannam@0: #ifndef _TEST_H_ cannam@0: #define _TEST_H_ cannam@0: cannam@0: #include cannam@0: cannam@0: #include cannam@0: cannam@0: class Test cannam@0: { cannam@0: public: cannam@0: virtual ~Test(); cannam@8: cannam@8: enum Option { Chris@39: NoOption = 0x0, Chris@39: NonDeterministic = 0x1, Chris@39: Verbose = 0x2, Chris@39: SingleTest = 0x4 cannam@8: }; cannam@8: typedef int Options; cannam@0: cannam@0: class Result { cannam@0: cannam@0: public: cannam@3: enum Code { Success, Note, Warning, Error }; cannam@0: cannam@8: Result() : m_code(Success) { } cannam@0: Result(Code c, std::string m) : m_code(c), m_message(m) { } cannam@0: cannam@3: Code code() const { return m_code; } cannam@3: std::string message() const { return m_message; } cannam@8: cannam@0: protected: cannam@0: Code m_code; cannam@0: std::string m_message; cannam@0: }; cannam@0: cannam@0: static Result success() { return Result(Result::Success, ""); } cannam@3: static Result note(std::string m) { return Result(Result::Note, m); } cannam@0: static Result warning(std::string m) { return Result(Result::Warning, m); } cannam@0: static Result error(std::string m) { return Result(Result::Error, m); } cannam@0: cannam@0: typedef std::vector Results; cannam@0: cannam@0: class FailedToLoadPlugin { }; cannam@0: cannam@0: // may throw FailedToLoadPlugin cannam@8: virtual Results test(std::string key, Options) = 0; cannam@0: cannam@0: protected: cannam@0: Test(); cannam@0: cannam@0: // may throw FailedToLoadPlugin cannam@0: Vamp::Plugin *load(std::string key, float rate = 44100); cannam@0: cannam@1: float **createBlock(size_t channels, size_t blocksize); cannam@1: void destroyBlock(float **blocks, size_t channels); cannam@1: cannam@3: float **createTestAudio(size_t channels, size_t blocksize, size_t blocks); cannam@3: void destroyTestAudio(float **audio, size_t channels); cannam@3: cannam@4: // use plugin's preferred step/block size, return them: cannam@1: bool initDefaults(Vamp::Plugin *, size_t &channels, cannam@1: size_t &step, size_t &block, Results &r); cannam@1: cannam@4: // use the given step/block size and an adapter: cannam@3: bool initAdapted(Vamp::Plugin *, size_t &channels, cannam@3: size_t step, size_t block, Results &r); cannam@3: cannam@0: void appendFeatures(Vamp::Plugin::FeatureSet &a, cannam@0: const Vamp::Plugin::FeatureSet &b); cannam@1: cannam@1: bool allFeaturesValid(const Vamp::Plugin::FeatureSet &); // i.e. no NaN/inf cannam@3: Chris@53: bool containsTimestamps(const Vamp::Plugin::FeatureSet &); Chris@53: Chris@61: void dumpFeature(const Vamp::Plugin::Feature &, bool showValues, Chris@61: const Vamp::Plugin::Feature *other = 0); Chris@52: void dump(const Vamp::Plugin::FeatureSet &, bool showValues = true); Chris@52: void dumpTwo(const Result &r, Chris@52: const Vamp::Plugin::FeatureSet &, Chris@52: const Vamp::Plugin::FeatureSet &); Chris@52: void dumpDiff(const Result &r, Chris@52: const Vamp::Plugin::FeatureSet &, Chris@52: const Vamp::Plugin::FeatureSet &); cannam@0: }; cannam@0: cannam@0: extern bool operator==(const Vamp::Plugin::FeatureSet &a, cannam@0: const Vamp::Plugin::FeatureSet &b); cannam@0: extern bool operator==(const Vamp::Plugin::FeatureList &a, cannam@0: const Vamp::Plugin::FeatureList &b); cannam@0: extern bool operator==(const Vamp::Plugin::Feature &a, cannam@0: const Vamp::Plugin::Feature &b); cannam@0: cannam@0: #endif cannam@0: