#include "ofxVamphost.h" using namespace std; int Vamphost::getRT(){ return rt.msec(); } enum Verbosity { PluginIds, PluginOutputIds, PluginInformation, PluginInformationDetailed }; static string header(string text, int level) { string out = '\n' + text + '\n'; for (size_t i = 0; i < text.length(); ++i) { out += (level == 1 ? '=' : level == 2 ? '-' : '~'); } out += '\n'; return out; } void printPluginPath(bool verbose) { if (verbose) { cout << "\nVamp plugin search path: "; } vector path = PluginHostAdapter::getPluginPath(); for (size_t i = 0; i < path.size(); ++i) { if (verbose) { cout << "[" << path[i] << "]"; } else { cout << path[i] << endl; } } if (verbose) cout << endl; } void enumeratePlugins(Verbosity verbosity) { PluginLoader *loader = PluginLoader::getInstance(); if (verbosity == PluginInformation) { cout << "\nVamp plugin libraries found in search path:" << endl; } vector plugins = loader->listPlugins(); typedef multimap 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; } } void printPluginCategoryList() { PluginLoader *loader = PluginLoader::getInstance(); vector plugins = loader->listPlugins(); set printedcats; for (size_t i = 0; i < plugins.size(); ++i) { PluginLoader::PluginKey key = plugins[i]; PluginLoader::PluginCategoryHierarchy category = loader->getPluginCategory(key); Plugin *plugin = loader->loadPlugin(key, 48000); if (!plugin) continue; string catstr = ""; if (category.empty()) catstr = '|'; else { for (size_t j = 0; j < category.size(); ++j) { catstr += category[j]; catstr += '|'; if (printedcats.find(catstr) == printedcats.end()) { std::cout << catstr << std::endl; printedcats.insert(catstr); } } } std::cout << catstr << key << ":::" << plugin->getName() << ":::" << plugin->getMaker() << ":::" << plugin->getDescription() << std::endl; } } int Vamphost::init(const string &soname,const string &id,const int &_channels,const int &_rate,const int &_outputNo,const string &_output){ //stuff that only happens once channels =_channels; rate=_rate; outputNo=_outputNo; output=_output; features[0.0f]=0; loader = PluginLoader::getInstance(); key = loader->composePluginKey(soname, id); plugin = loader->loadPlugin(key, _rate, PluginLoader::ADAPT_ALL_SAFE); if (!plugin) { cerr << ": ERROR: Failed to load plugin \"" << id << "\" from library \"" << soname << "\"" << endl; return -1; } cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl; blockSize = plugin->getPreferredBlockSize(); stepSize = plugin->getPreferredStepSize(); if (blockSize == 0) { blockSize = 1024; } if (stepSize == 0) { if (plugin->getInputDomain() == Plugin::FrequencyDomain) { stepSize = blockSize/2; } else { stepSize = blockSize; } } else if (stepSize > blockSize) { cerr << "WARNING: stepSize " << stepSize << " > blockSize " << blockSize << ", resetting blockSize to "; if (plugin->getInputDomain() == Plugin::FrequencyDomain) { blockSize = stepSize * 2; } else { blockSize = stepSize; } cerr << blockSize << endl; } overlapSize = blockSize - stepSize; currentStep = 0; finalStepsRemaining = max(1, (blockSize / stepSize) - 1); // at end of file, this many part-silent frames needed after we hit EOF plugbuf = new float*[channels]; for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2]; cerr << "Using block size = " << blockSize << ", step size = " << stepSize << endl; // The channel queries here are for informational purposes only -- // a PluginChannelAdapter is being used automatically behind the // scenes, and it will take case of any channel mismatch int minch = plugin->getMinChannelCount(); int maxch = plugin->getMaxChannelCount(); cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl; cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl; Plugin::OutputList outputs = plugin->getOutputDescriptors(); Plugin::OutputDescriptor od; int returnValue = 1; int prog = 0; RealTime rt; PluginWrapper *wrapper = 0; RealTime adjustment = RealTime::zeroTime; if (outputs.empty()) { cerr << "ERROR: Plugin has no outputs!" << endl; return -1; } if (outputNo < 0) { for (size_t oi = 0; oi < outputs.size(); ++oi) { if (outputs[oi].identifier == output) { outputNo = oi; break; } } if (outputNo < 0) { cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl; return -1; } } else { if (int(outputs.size()) <= outputNo) { cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl; return -1; } } od = outputs[outputNo]; cerr << "Output is: \"" << od.identifier << "\"" << endl; if (!plugin->initialise(channels, stepSize, blockSize)) { cerr << "ERROR: Plugin initialise (channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " << blockSize << ") failed." << endl; return -1; } wrapper = dynamic_cast(plugin); if (wrapper) { // See documentation for // PluginInputDomainAdapter::getTimestampAdjustment PluginInputDomainAdapter *ida =wrapper->getWrapper(); if (ida) adjustment = ida->getTimestampAdjustment(); } //everything is prepared to start consuming data in blocks in_block=0; blocks_processed=0; currentStep=0; featureNo=1; avg=0.0f; num=0; numFeat=0; return blockSize; } void Vamphost::process_frame(float *data,int samples_in_frame){ // // //plugbuf[0]=data; // // int sample=0; //process the whole frame which may be f>1getIdentifier()<<" processed block "<process(plugbuf, rt); for (unsigned int i = 0; i < feat[outputNo].size(); ++i) { features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo; featureNo++; numFeat++; } //shunt it down for (int i=0;iprocess(plugbuf, rt); for (unsigned int i = 0; i < feat[outputNo].size(); ++i) { features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo; featureNo++; } feat=plugin->getRemainingFeatures(); for (unsigned int i = 0; i < feat[outputNo].size(); ++i) { features[((float)feat[outputNo][i].timestamp.sec)+(((float)feat[outputNo][i].timestamp.nsec)*.000000001)]=featureNo; featureNo++; } cerr<getIdentifier()<<" found "<<(features.size()-1)<<" features"<