Example #1
0
Test::Results
TestDefaultParameters::test(string key, Options options)
{
    Plugin::FeatureSet f[2];
    int rate = 44100;
    Results r;
    float **data = 0;
    size_t channels = 0;
    size_t count = 100;

    for (int run = 0; run < 2; ++run) {
        auto_ptr<Plugin> p(load(key, rate));
	if (p->getParameterDescriptors().empty()) return r;
	if (run == 1) {
            Plugin::ParameterList pl = p->getParameterDescriptors();
            for (int i = 0; i < (int)pl.size(); ++i) {
                if (p->getParameter(pl[i].identifier) != pl[i].defaultValue) {
                    if (options & Verbose) {
                        cout << "Parameter: " << pl[i].identifier << endl;
                        cout << "Expected: " << pl[i].defaultValue << endl;
                        cout << "Actual: " << p->getParameter(pl[i].identifier) << endl;
                    }
                    r.push_back(error("Not all parameters have their default values when queried directly after construction"));
                }
                p->setParameter(pl[i].identifier, pl[i].defaultValue);
            }
        }
        if (!initAdapted(p.get(), channels, _step, _step, r)) return r;
        if (!data) data = createTestAudio(channels, _step, count);
        for (size_t i = 0; i < count; ++i) {
#ifdef __GNUC__
            float *ptr[channels];
#else
            float **ptr = (float **)alloca(channels * sizeof(float));
#endif
            size_t idx = i * _step;
            for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
            RealTime timestamp = RealTime::frame2RealTime(idx, rate);
            Plugin::FeatureSet fs = p->process(ptr, timestamp);
            appendFeatures(f[run], fs);
        }
        Plugin::FeatureSet fs = p->getRemainingFeatures();
        appendFeatures(f[run], fs);
    }
    if (data) destroyTestAudio(data, channels);

    if (!(f[0] == f[1])) {
        string message = "Explicitly setting parameters to their supposed default values changes the results";
        Result res;
        if (options & NonDeterministic) res = note(message);
        else res = error(message);
        if (options & Verbose) dumpDiff(res, f[0], f[1]);
        r.push_back(res);
    } else {
        r.push_back(success());
    }

    return r;
}
void
enumeratePlugins(Verbosity verbosity)
{
    PluginLoader *loader = PluginLoader::getInstance();

    if (verbosity == PluginInformation) {
        cout << "\nVamp plugin libraries found in search path:" << endl;
    }

    vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
    typedef multimap<string, PluginLoader::PluginKey>
        LibraryMap;
    LibraryMap libraryMap;

    for (size_t i = 0; i < plugins.size(); ++i) {
        string path = loader->getLibraryPathForPlugin(plugins[i]);
        libraryMap.insert(LibraryMap::value_type(path, plugins[i]));
    }

    string prevPath = "";
    int index = 0;

    for (LibraryMap::iterator i = libraryMap.begin();
         i != libraryMap.end(); ++i) {
        
        string path = i->first;
        PluginLoader::PluginKey key = i->second;

        if (path != prevPath) {
            prevPath = path;
            index = 0;
            if (verbosity == PluginInformation) {
                cout << "\n  " << path << ":" << endl;
            } else if (verbosity == PluginInformationDetailed) {
                string::size_type ki = i->second.find(':');
                string text = "Library \"" + i->second.substr(0, ki) + "\"";
                cout << "\n" << header(text, 1);
            }
        }

        Plugin *plugin = loader->loadPlugin(key, 48000);
        if (plugin) {

            char c = char('A' + index);
            if (c > 'Z') c = char('a' + (index - 26));

            PluginLoader::PluginCategoryHierarchy category =
                loader->getPluginCategory(key);
            string catstr;
            if (!category.empty()) {
                for (size_t ci = 0; ci < category.size(); ++ci) {
                    if (ci > 0) catstr += " > ";
                        catstr += category[ci];
                }
            }

            if (verbosity == PluginInformation) {

                cout << "    [" << c << "] [v"
                     << plugin->getVampApiVersion() << "] "
                     << plugin->getName() << ", \""
                     << plugin->getIdentifier() << "\"" << " ["
                     << plugin->getMaker() << "]" << endl;
                
                if (catstr != "") {
                    cout << "       > " << catstr << endl;
                }

                if (plugin->getDescription() != "") {
                    cout << "        - " << plugin->getDescription() << endl;
                }

            } else if (verbosity == PluginInformationDetailed) {

                cout << header(plugin->getName(), 2);
                cout << " - Identifier:         "
                     << key << endl;
                cout << " - Plugin Version:     " 
                     << plugin->getPluginVersion() << endl;
                cout << " - Vamp API Version:   "
                     << plugin->getVampApiVersion() << endl;
                cout << " - Maker:              \""
                     << plugin->getMaker() << "\"" << endl;
                cout << " - Copyright:          \""
                     << plugin->getCopyright() << "\"" << endl;
                cout << " - Description:        \""
                     << plugin->getDescription() << "\"" << endl;
                cout << " - Input Domain:       "
                     << (plugin->getInputDomain() == Vamp::Plugin::TimeDomain ?
                         "Time Domain" : "Frequency Domain") << endl;
                cout << " - Default Step Size:  " 
                     << plugin->getPreferredStepSize() << endl;
                cout << " - Default Block Size: " 
                     << plugin->getPreferredBlockSize() << endl;
                cout << " - Minimum Channels:   " 
                     << plugin->getMinChannelCount() << endl;
                cout << " - Maximum Channels:   " 
                     << plugin->getMaxChannelCount() << endl;

            } else if (verbosity == PluginIds) {
                cout << "vamp:" << key << endl;
            }
            
            Plugin::OutputList outputs =
                plugin->getOutputDescriptors();

            if (verbosity == PluginInformationDetailed) {

                Plugin::ParameterList params = plugin->getParameterDescriptors();
                for (size_t j = 0; j < params.size(); ++j) {
                    Plugin::ParameterDescriptor &pd(params[j]);
                    cout << "\nParameter " << j+1 << ": \"" << pd.name << "\"" << endl;
                    cout << " - Identifier:         " << pd.identifier << endl;
                    cout << " - Description:        \"" << pd.description << "\"" << endl;
                    if (pd.unit != "") {
                        cout << " - Unit:               " << pd.unit << endl;
                    }
                    cout << " - Range:              ";
                    cout << pd.minValue << " -> " << pd.maxValue << endl;
                    cout << " - Default:            ";
                    cout << pd.defaultValue << endl;
                    if (pd.isQuantized) {
                        cout << " - Quantize Step:      "
                             << pd.quantizeStep << endl;
                    }
                    if (!pd.valueNames.empty()) {
                        cout << " - Value Names:        ";
                        for (size_t k = 0; k < pd.valueNames.size(); ++k) {
                            if (k > 0) cout << ", ";
                            cout << "\"" << pd.valueNames[k] << "\"";
                        }
                        cout << endl;
                    }
                }

                if (outputs.empty()) {
                    cout << "\n** Note: This plugin reports no outputs!" << endl;
                }
                for (size_t j = 0; j < outputs.size(); ++j) {
                    Plugin::OutputDescriptor &od(outputs[j]);
                    cout << "\nOutput " << j+1 << ": \"" << od.name << "\"" << endl;
                    cout << " - Identifier:         " << od.identifier << endl;
                    cout << " - Description:        \"" << od.description << "\"" << endl;
                    if (od.unit != "") {
                        cout << " - Unit:               " << od.unit << endl;
                    }
                    if (od.hasFixedBinCount) {
                        cout << " - Default Bin Count:  " << od.binCount << endl;
                    }
                    if (!od.binNames.empty()) {
                        bool have = false;
                        for (size_t k = 0; k < od.binNames.size(); ++k) {
                            if (od.binNames[k] != "") {
                                have = true; break;
                            }
                        }
                        if (have) {
                            cout << " - Bin Names:          ";
                            for (size_t k = 0; k < od.binNames.size(); ++k) {
                                if (k > 0) cout << ", ";
                                cout << "\"" << od.binNames[k] << "\"";
                            }
                            cout << endl;
                        }
                    }
                    if (od.hasKnownExtents) {
                        cout << " - Default Extents:    ";
                        cout << od.minValue << " -> " << od.maxValue << endl;
                    }
                    if (od.isQuantized) {
                        cout << " - Quantize Step:      "
                             << od.quantizeStep << endl;
                    }
                    cout << " - Sample Type:        "
                         << (od.sampleType ==
                             Plugin::OutputDescriptor::OneSamplePerStep ?
                             "One Sample Per Step" :
                             od.sampleType ==
                             Plugin::OutputDescriptor::FixedSampleRate ?
                             "Fixed Sample Rate" :
                             "Variable Sample Rate") << endl;
                    if (od.sampleType !=
                        Plugin::OutputDescriptor::OneSamplePerStep) {
                        cout << " - Default Rate:       "
                             << od.sampleRate << endl;
                    }
                    cout << " - Has Duration:       "
                         << (od.hasDuration ? "Yes" : "No") << endl;
                }
            }

            if (outputs.size() > 1 || verbosity == PluginOutputIds) {
                for (size_t j = 0; j < outputs.size(); ++j) {
                    if (verbosity == PluginInformation) {
                        cout << "         (" << j << ") "
                             << outputs[j].name << ", \""
                             << outputs[j].identifier << "\"" << endl;
                        if (outputs[j].description != "") {
                            cout << "             - " 
                                 << outputs[j].description << endl;
                        }
                    } else if (verbosity == PluginOutputIds) {
                        cout << "vamp:" << key << ":" << outputs[j].identifier << endl;
                    }
                }
            }

            ++index;

            delete plugin;
        }
    }

    if (verbosity == PluginInformation ||
        verbosity == PluginInformationDetailed) {
        cout << endl;
    }
}
Example #3
0
Test::Results
TestParametersOnReset::test(string key, Options options)
{
    Plugin::FeatureSet f[2];
    int rate = 44100;
    Results r;
    float **data = 0;
    size_t channels = 0;
    size_t count = 100;

    for (int run = 0; run < 2; ++run) {
        auto_ptr<Plugin> p(load(key, rate));
	if (p->getParameterDescriptors().empty()) return r;

        // Set all parameters to non-default values

        Plugin::ParameterList pl = p->getParameterDescriptors();

        for (int i = 0; i < (int)pl.size(); ++i) {

            // Half-way between default and max value, seems a
            // reasonable guess for something to set it to. We want to
            // avoid the real extremes because they can sometimes be
            // very slow, and we want to avoid setting everything to
            // the same values (e.g. min) because plugins will
            // sometimes legitimately reject that.

            // Remember to take into account quantization

            float value = (pl[i].defaultValue + pl[i].maxValue) / 2;

            if (pl[i].isQuantized) {
                value = round(value / pl[i].quantizeStep) * pl[i].quantizeStep;
            }

            if (value > pl[i].maxValue) {
                value = pl[i].maxValue;
            }
            if (value < pl[i].minValue) {
                value = pl[i].minValue;
            }
            if (value == pl[i].defaultValue) {
                if (pl[i].defaultValue == pl[i].minValue) {
                    value = pl[i].maxValue;
                } else {
                    value = pl[i].minValue;
                }
            }

            p->setParameter(pl[i].identifier, value);
        }

        if (!initAdapted(p.get(), channels, _step, _step, r)) {

            // OK, plugin didn't like that. Let's try a different tack
            // -- set everything to min except those parameters whose
            // default is min, and set those to half way instead
            
            for (int i = 0; i < (int)pl.size(); ++i) {
                float value = pl[i].minValue;
                if (value == pl[i].defaultValue) {
                    value = (pl[i].maxValue + pl[i].minValue) / 2;
                    value = ceil(value / pl[i].quantizeStep) * pl[i].quantizeStep;
                    if (value > pl[i].maxValue) {
                        value = pl[i].maxValue;
                    }
                }
                p->setParameter(pl[i].identifier, value);
            }

            r = Results();
            if (!initAdapted(p.get(), channels, _step, _step, r)) {
                // Still didn't work, give up
                return r;
            }
        }

        //  First run: construct, set params, init, process
        // Second run: construct, set params, init, reset, process
        // We expect these to produce the same results
        if (run == 1) p->reset();

        if (!data) data = createTestAudio(channels, _step, count);
        for (size_t i = 0; i < count; ++i) {
#ifdef __GNUC__
            float *ptr[channels];
#else
            float **ptr = (float **)alloca(channels * sizeof(float));
#endif
            size_t idx = i * _step;
            for (size_t c = 0; c < channels; ++c) ptr[c] = data[c] + idx;
            RealTime timestamp = RealTime::frame2RealTime(idx, rate);
            Plugin::FeatureSet fs = p->process(ptr, timestamp);
            appendFeatures(f[run], fs);
        }
        Plugin::FeatureSet fs = p->getRemainingFeatures();
        appendFeatures(f[run], fs);
    }
    if (data) destroyTestAudio(data, channels);

    if (!(f[0] == f[1])) {
        string message = "Call to reset after setting parameters, but before processing, changes the results (parameter values not retained through reset?)";
        Result res;
        if (options & NonDeterministic) res = note(message);
        else res = error(message);
        if (options & Verbose) dumpDiff(res, f[0], f[1]);
        r.push_back(res);
    } else {
        r.push_back(success());
    }

    return r;
}