cannam@0: cannam@0:
cannam@0:00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@0: 00002 cannam@0: 00003 /* cannam@0: 00004 Vamp cannam@0: 00005 cannam@0: 00006 An API for audio analysis and feature extraction plugins. cannam@0: 00007 cannam@0: 00008 Centre for Digital Music, Queen Mary, University of London. cannam@0: 00009 Copyright 2006 Chris Cannam. cannam@0: 00010 cannam@0: 00011 Permission is hereby granted, free of charge, to any person cannam@0: 00012 obtaining a copy of this software and associated documentation cannam@0: 00013 files (the "Software"), to deal in the Software without cannam@0: 00014 restriction, including without limitation the rights to use, copy, cannam@0: 00015 modify, merge, publish, distribute, sublicense, and/or sell copies cannam@0: 00016 of the Software, and to permit persons to whom the Software is cannam@0: 00017 furnished to do so, subject to the following conditions: cannam@0: 00018 cannam@0: 00019 The above copyright notice and this permission notice shall be cannam@0: 00020 included in all copies or substantial portions of the Software. cannam@0: 00021 cannam@0: 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, cannam@0: 00023 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF cannam@0: 00024 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND cannam@0: 00025 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR cannam@0: 00026 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF cannam@0: 00027 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION cannam@0: 00028 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cannam@0: 00029 cannam@0: 00030 Except as contained in this notice, the names of the Centre for cannam@0: 00031 Digital Music; Queen Mary, University of London; and Chris Cannam cannam@0: 00032 shall not be used in advertising or otherwise to promote the sale, cannam@0: 00033 use or other dealings in this Software without prior written cannam@0: 00034 authorization. cannam@0: 00035 */ cannam@0: 00036 cannam@0: 00037 #include "PluginAdapter.h" cannam@0: 00038 cannam@0: 00039 #include <cstring> cannam@0: 00040 #include <cstdlib> cannam@0: 00041 cannam@0: 00042 //#define DEBUG_PLUGIN_ADAPTER 1 cannam@0: 00043 cannam@0: 00044 namespace Vamp { cannam@0: 00045 cannam@0: 00046 class PluginAdapterBase::Impl cannam@0: 00047 { cannam@0: 00048 public: cannam@0: 00049 Impl(PluginAdapterBase *); cannam@0: 00050 ~Impl(); cannam@0: 00051 cannam@0: 00052 const VampPluginDescriptor *getDescriptor(); cannam@0: 00053 cannam@0: 00054 protected: cannam@0: 00055 PluginAdapterBase *m_base; cannam@0: 00056 cannam@0: 00057 static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc, cannam@0: 00058 float inputSampleRate); cannam@0: 00059 cannam@0: 00060 static void vampCleanup(VampPluginHandle handle); cannam@0: 00061 cannam@0: 00062 static int vampInitialise(VampPluginHandle handle, unsigned int channels, cannam@0: 00063 unsigned int stepSize, unsigned int blockSize); cannam@0: 00064 cannam@0: 00065 static void vampReset(VampPluginHandle handle); cannam@0: 00066 cannam@0: 00067 static float vampGetParameter(VampPluginHandle handle, int param); cannam@0: 00068 static void vampSetParameter(VampPluginHandle handle, int param, float value); cannam@0: 00069 cannam@0: 00070 static unsigned int vampGetCurrentProgram(VampPluginHandle handle); cannam@0: 00071 static void vampSelectProgram(VampPluginHandle handle, unsigned int program); cannam@0: 00072 cannam@0: 00073 static unsigned int vampGetPreferredStepSize(VampPluginHandle handle); cannam@0: 00074 static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle); cannam@0: 00075 static unsigned int vampGetMinChannelCount(VampPluginHandle handle); cannam@0: 00076 static unsigned int vampGetMaxChannelCount(VampPluginHandle handle); cannam@0: 00077 cannam@0: 00078 static unsigned int vampGetOutputCount(VampPluginHandle handle); cannam@0: 00079 cannam@0: 00080 static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle, cannam@0: 00081 unsigned int i); cannam@0: 00082 cannam@0: 00083 static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc); cannam@0: 00084 cannam@0: 00085 static VampFeatureList *vampProcess(VampPluginHandle handle, cannam@0: 00086 const float *const *inputBuffers, cannam@0: 00087 int sec, cannam@0: 00088 int nsec); cannam@0: 00089 cannam@0: 00090 static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle); cannam@0: 00091 cannam@0: 00092 static void vampReleaseFeatureSet(VampFeatureList *fs); cannam@0: 00093 cannam@0: 00094 void cleanup(Plugin *plugin); cannam@0: 00095 void checkOutputMap(Plugin *plugin); cannam@0: 00096 unsigned int getOutputCount(Plugin *plugin); cannam@0: 00097 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin, cannam@0: 00098 unsigned int i); cannam@0: 00099 VampFeatureList *process(Plugin *plugin, cannam@0: 00100 const float *const *inputBuffers, cannam@0: 00101 int sec, int nsec); cannam@0: 00102 VampFeatureList *getRemainingFeatures(Plugin *plugin); cannam@0: 00103 VampFeatureList *convertFeatures(Plugin *plugin, cannam@0: 00104 const Plugin::FeatureSet &features); cannam@0: 00105 cannam@0: 00106 // maps both plugins and descriptors to adapters cannam@0: 00107 typedef std::map<const void *, Impl *> AdapterMap; cannam@0: 00108 static AdapterMap *m_adapterMap; cannam@0: 00109 static Impl *lookupAdapter(VampPluginHandle); cannam@0: 00110 cannam@0: 00111 bool m_populated; cannam@0: 00112 VampPluginDescriptor m_descriptor; cannam@0: 00113 Plugin::ParameterList m_parameters; cannam@0: 00114 Plugin::ProgramList m_programs; cannam@0: 00115 cannam@0: 00116 typedef std::map<Plugin *, Plugin::OutputList *> OutputMap; cannam@0: 00117 OutputMap m_pluginOutputs; cannam@0: 00118 cannam@0: 00119 std::map<Plugin *, VampFeatureList *> m_fs; cannam@0: 00120 std::map<Plugin *, std::vector<size_t> > m_fsizes; cannam@0: 00121 std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes; cannam@0: 00122 void resizeFS(Plugin *plugin, int n); cannam@0: 00123 void resizeFL(Plugin *plugin, int n, size_t sz); cannam@0: 00124 void resizeFV(Plugin *plugin, int n, int j, size_t sz); cannam@0: 00125 }; cannam@0: 00126 cannam@0: 00127 PluginAdapterBase::PluginAdapterBase() cannam@0: 00128 { cannam@0: 00129 m_impl = new Impl(this); cannam@0: 00130 } cannam@0: 00131 cannam@0: 00132 PluginAdapterBase::~PluginAdapterBase() cannam@0: 00133 { cannam@0: 00134 delete m_impl; cannam@0: 00135 } cannam@0: 00136 cannam@0: 00137 const VampPluginDescriptor * cannam@0: 00138 PluginAdapterBase::getDescriptor() cannam@0: 00139 { cannam@0: 00140 return m_impl->getDescriptor(); cannam@0: 00141 } cannam@0: 00142 cannam@0: 00143 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) : cannam@0: 00144 m_base(base), cannam@0: 00145 m_populated(false) cannam@0: 00146 { cannam@0: 00147 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00148 std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl; cannam@0: 00149 #endif cannam@0: 00150 } cannam@0: 00151 cannam@0: 00152 const VampPluginDescriptor * cannam@0: 00153 PluginAdapterBase::Impl::getDescriptor() cannam@0: 00154 { cannam@0: 00155 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00156 std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl; cannam@0: 00157 #endif cannam@0: 00158 cannam@0: 00159 if (m_populated) return &m_descriptor; cannam@0: 00160 cannam@0: 00161 Plugin *plugin = m_base->createPlugin(48000); cannam@0: 00162 cannam@0: 00163 if (plugin->getVampApiVersion() != VAMP_API_VERSION) { cannam@0: 00164 std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: " cannam@0: 00165 << "Plugin object API version " cannam@0: 00166 << plugin->getVampApiVersion() cannam@0: 00167 << " does not match actual API version " cannam@0: 00168 << VAMP_API_VERSION << std::endl; cannam@0: 00169 delete plugin; cannam@0: 00170 return 0; cannam@0: 00171 } cannam@0: 00172 cannam@0: 00173 m_parameters = plugin->getParameterDescriptors(); cannam@0: 00174 m_programs = plugin->getPrograms(); cannam@0: 00175 cannam@0: 00176 m_descriptor.vampApiVersion = plugin->getVampApiVersion(); cannam@0: 00177 m_descriptor.identifier = strdup(plugin->getIdentifier().c_str()); cannam@0: 00178 m_descriptor.name = strdup(plugin->getName().c_str()); cannam@0: 00179 m_descriptor.description = strdup(plugin->getDescription().c_str()); cannam@0: 00180 m_descriptor.maker = strdup(plugin->getMaker().c_str()); cannam@0: 00181 m_descriptor.pluginVersion = plugin->getPluginVersion(); cannam@0: 00182 m_descriptor.copyright = strdup(plugin->getCopyright().c_str()); cannam@0: 00183 cannam@0: 00184 m_descriptor.parameterCount = m_parameters.size(); cannam@0: 00185 m_descriptor.parameters = (const VampParameterDescriptor **) cannam@0: 00186 malloc(m_parameters.size() * sizeof(VampParameterDescriptor)); cannam@0: 00187 cannam@0: 00188 unsigned int i; cannam@0: 00189 cannam@0: 00190 for (i = 0; i < m_parameters.size(); ++i) { cannam@0: 00191 VampParameterDescriptor *desc = (VampParameterDescriptor *) cannam@0: 00192 malloc(sizeof(VampParameterDescriptor)); cannam@0: 00193 desc->identifier = strdup(m_parameters[i].identifier.c_str()); cannam@0: 00194 desc->name = strdup(m_parameters[i].name.c_str()); cannam@0: 00195 desc->description = strdup(m_parameters[i].description.c_str()); cannam@0: 00196 desc->unit = strdup(m_parameters[i].unit.c_str()); cannam@0: 00197 desc->minValue = m_parameters[i].minValue; cannam@0: 00198 desc->maxValue = m_parameters[i].maxValue; cannam@0: 00199 desc->defaultValue = m_parameters[i].defaultValue; cannam@0: 00200 desc->isQuantized = m_parameters[i].isQuantized; cannam@0: 00201 desc->quantizeStep = m_parameters[i].quantizeStep; cannam@0: 00202 desc->valueNames = 0; cannam@0: 00203 if (desc->isQuantized && !m_parameters[i].valueNames.empty()) { cannam@0: 00204 desc->valueNames = (const char **) cannam@0: 00205 malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *)); cannam@0: 00206 for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) { cannam@0: 00207 desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str()); cannam@0: 00208 } cannam@0: 00209 desc->valueNames[m_parameters[i].valueNames.size()] = 0; cannam@0: 00210 } cannam@0: 00211 m_descriptor.parameters[i] = desc; cannam@0: 00212 } cannam@0: 00213 cannam@0: 00214 m_descriptor.programCount = m_programs.size(); cannam@0: 00215 m_descriptor.programs = (const char **) cannam@0: 00216 malloc(m_programs.size() * sizeof(const char *)); cannam@0: 00217 cannam@0: 00218 for (i = 0; i < m_programs.size(); ++i) { cannam@0: 00219 m_descriptor.programs[i] = strdup(m_programs[i].c_str()); cannam@0: 00220 } cannam@0: 00221 cannam@0: 00222 if (plugin->getInputDomain() == Plugin::FrequencyDomain) { cannam@0: 00223 m_descriptor.inputDomain = vampFrequencyDomain; cannam@0: 00224 } else { cannam@0: 00225 m_descriptor.inputDomain = vampTimeDomain; cannam@0: 00226 } cannam@0: 00227 cannam@0: 00228 m_descriptor.instantiate = vampInstantiate; cannam@0: 00229 m_descriptor.cleanup = vampCleanup; cannam@0: 00230 m_descriptor.initialise = vampInitialise; cannam@0: 00231 m_descriptor.reset = vampReset; cannam@0: 00232 m_descriptor.getParameter = vampGetParameter; cannam@0: 00233 m_descriptor.setParameter = vampSetParameter; cannam@0: 00234 m_descriptor.getCurrentProgram = vampGetCurrentProgram; cannam@0: 00235 m_descriptor.selectProgram = vampSelectProgram; cannam@0: 00236 m_descriptor.getPreferredStepSize = vampGetPreferredStepSize; cannam@0: 00237 m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize; cannam@0: 00238 m_descriptor.getMinChannelCount = vampGetMinChannelCount; cannam@0: 00239 m_descriptor.getMaxChannelCount = vampGetMaxChannelCount; cannam@0: 00240 m_descriptor.getOutputCount = vampGetOutputCount; cannam@0: 00241 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor; cannam@0: 00242 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor; cannam@0: 00243 m_descriptor.process = vampProcess; cannam@0: 00244 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures; cannam@0: 00245 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet; cannam@0: 00246 cannam@0: 00247 if (!m_adapterMap) { cannam@0: 00248 m_adapterMap = new AdapterMap; cannam@0: 00249 } cannam@0: 00250 (*m_adapterMap)[&m_descriptor] = this; cannam@0: 00251 cannam@0: 00252 delete plugin; cannam@0: 00253 cannam@0: 00254 m_populated = true; cannam@0: 00255 return &m_descriptor; cannam@0: 00256 } cannam@0: 00257 cannam@0: 00258 PluginAdapterBase::Impl::~Impl() cannam@0: 00259 { cannam@0: 00260 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00261 std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl; cannam@0: 00262 #endif cannam@0: 00263 cannam@0: 00264 if (!m_populated) return; cannam@0: 00265 cannam@0: 00266 free((void *)m_descriptor.identifier); cannam@0: 00267 free((void *)m_descriptor.name); cannam@0: 00268 free((void *)m_descriptor.description); cannam@0: 00269 free((void *)m_descriptor.maker); cannam@0: 00270 free((void *)m_descriptor.copyright); cannam@0: 00271 cannam@0: 00272 for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) { cannam@0: 00273 const VampParameterDescriptor *desc = m_descriptor.parameters[i]; cannam@0: 00274 free((void *)desc->identifier); cannam@0: 00275 free((void *)desc->name); cannam@0: 00276 free((void *)desc->description); cannam@0: 00277 free((void *)desc->unit); cannam@0: 00278 if (desc->valueNames) { cannam@0: 00279 for (unsigned int j = 0; desc->valueNames[j]; ++j) { cannam@0: 00280 free((void *)desc->valueNames[j]); cannam@0: 00281 } cannam@0: 00282 free((void *)desc->valueNames); cannam@0: 00283 } cannam@0: 00284 } cannam@0: 00285 free((void *)m_descriptor.parameters); cannam@0: 00286 cannam@0: 00287 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) { cannam@0: 00288 free((void *)m_descriptor.programs[i]); cannam@0: 00289 } cannam@0: 00290 free((void *)m_descriptor.programs); cannam@0: 00291 cannam@0: 00292 if (m_adapterMap) { cannam@0: 00293 cannam@0: 00294 m_adapterMap->erase(&m_descriptor); cannam@0: 00295 cannam@0: 00296 if (m_adapterMap->empty()) { cannam@0: 00297 delete m_adapterMap; cannam@0: 00298 m_adapterMap = 0; cannam@0: 00299 } cannam@0: 00300 } cannam@0: 00301 } cannam@0: 00302 cannam@0: 00303 PluginAdapterBase::Impl * cannam@0: 00304 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle) cannam@0: 00305 { cannam@0: 00306 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00307 std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl; cannam@0: 00308 #endif cannam@0: 00309 cannam@0: 00310 if (!m_adapterMap) return 0; cannam@0: 00311 AdapterMap::const_iterator i = m_adapterMap->find(handle); cannam@0: 00312 if (i == m_adapterMap->end()) return 0; cannam@0: 00313 return i->second; cannam@0: 00314 } cannam@0: 00315 cannam@0: 00316 VampPluginHandle cannam@0: 00317 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc, cannam@0: 00318 float inputSampleRate) cannam@0: 00319 { cannam@0: 00320 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00321 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl; cannam@0: 00322 #endif cannam@0: 00323 cannam@0: 00324 if (!m_adapterMap) { cannam@0: 00325 m_adapterMap = new AdapterMap(); cannam@0: 00326 } cannam@0: 00327 cannam@0: 00328 if (m_adapterMap->find(desc) == m_adapterMap->end()) { cannam@0: 00329 std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl; cannam@0: 00330 return 0; cannam@0: 00331 } cannam@0: 00332 cannam@0: 00333 Impl *adapter = (*m_adapterMap)[desc]; cannam@0: 00334 if (desc != &adapter->m_descriptor) return 0; cannam@0: 00335 cannam@0: 00336 Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate); cannam@0: 00337 if (plugin) { cannam@0: 00338 (*m_adapterMap)[plugin] = adapter; cannam@0: 00339 } cannam@0: 00340 cannam@0: 00341 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00342 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl; cannam@0: 00343 #endif cannam@0: 00344 cannam@0: 00345 return plugin; cannam@0: 00346 } cannam@0: 00347 cannam@0: 00348 void cannam@0: 00349 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle) cannam@0: 00350 { cannam@0: 00351 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00352 std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl; cannam@0: 00353 #endif cannam@0: 00354 cannam@0: 00355 Impl *adapter = lookupAdapter(handle); cannam@0: 00356 if (!adapter) { cannam@0: 00357 delete ((Plugin *)handle); cannam@0: 00358 return; cannam@0: 00359 } cannam@0: 00360 adapter->cleanup(((Plugin *)handle)); cannam@0: 00361 } cannam@0: 00362 cannam@0: 00363 int cannam@0: 00364 PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle, cannam@0: 00365 unsigned int channels, cannam@0: 00366 unsigned int stepSize, cannam@0: 00367 unsigned int blockSize) cannam@0: 00368 { cannam@0: 00369 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00370 std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl; cannam@0: 00371 #endif cannam@0: 00372 cannam@0: 00373 bool result = ((Plugin *)handle)->initialise cannam@0: 00374 (channels, stepSize, blockSize); cannam@0: 00375 return result ? 1 : 0; cannam@0: 00376 } cannam@0: 00377 cannam@0: 00378 void cannam@0: 00379 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle) cannam@0: 00380 { cannam@0: 00381 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00382 std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl; cannam@0: 00383 #endif cannam@0: 00384 cannam@0: 00385 ((Plugin *)handle)->reset(); cannam@0: 00386 } cannam@0: 00387 cannam@0: 00388 float cannam@0: 00389 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle, cannam@0: 00390 int param) cannam@0: 00391 { cannam@0: 00392 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00393 std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl; cannam@0: 00394 #endif cannam@0: 00395 cannam@0: 00396 Impl *adapter = lookupAdapter(handle); cannam@0: 00397 if (!adapter) return 0.0; cannam@0: 00398 Plugin::ParameterList &list = adapter->m_parameters; cannam@0: 00399 return ((Plugin *)handle)->getParameter(list[param].identifier); cannam@0: 00400 } cannam@0: 00401 cannam@0: 00402 void cannam@0: 00403 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle, cannam@0: 00404 int param, float value) cannam@0: 00405 { cannam@0: 00406 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00407 std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl; cannam@0: 00408 #endif cannam@0: 00409 cannam@0: 00410 Impl *adapter = lookupAdapter(handle); cannam@0: 00411 if (!adapter) return; cannam@0: 00412 Plugin::ParameterList &list = adapter->m_parameters; cannam@0: 00413 ((Plugin *)handle)->setParameter(list[param].identifier, value); cannam@0: 00414 } cannam@0: 00415 cannam@0: 00416 unsigned int cannam@0: 00417 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle) cannam@0: 00418 { cannam@0: 00419 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00420 std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl; cannam@0: 00421 #endif cannam@0: 00422 cannam@0: 00423 Impl *adapter = lookupAdapter(handle); cannam@0: 00424 if (!adapter) return 0; cannam@0: 00425 Plugin::ProgramList &list = adapter->m_programs; cannam@0: 00426 std::string program = ((Plugin *)handle)->getCurrentProgram(); cannam@0: 00427 for (unsigned int i = 0; i < list.size(); ++i) { cannam@0: 00428 if (list[i] == program) return i; cannam@0: 00429 } cannam@0: 00430 return 0; cannam@0: 00431 } cannam@0: 00432 cannam@0: 00433 void cannam@0: 00434 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle, cannam@0: 00435 unsigned int program) cannam@0: 00436 { cannam@0: 00437 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00438 std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl; cannam@0: 00439 #endif cannam@0: 00440 cannam@0: 00441 Impl *adapter = lookupAdapter(handle); cannam@0: 00442 if (!adapter) return; cannam@0: 00443 Plugin::ProgramList &list = adapter->m_programs; cannam@0: 00444 ((Plugin *)handle)->selectProgram(list[program]); cannam@0: 00445 } cannam@0: 00446 cannam@0: 00447 unsigned int cannam@0: 00448 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle) cannam@0: 00449 { cannam@0: 00450 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00451 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl; cannam@0: 00452 #endif cannam@0: 00453 cannam@0: 00454 return ((Plugin *)handle)->getPreferredStepSize(); cannam@0: 00455 } cannam@0: 00456 cannam@0: 00457 unsigned int cannam@0: 00458 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle) cannam@0: 00459 { cannam@0: 00460 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00461 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl; cannam@0: 00462 #endif cannam@0: 00463 cannam@0: 00464 return ((Plugin *)handle)->getPreferredBlockSize(); cannam@0: 00465 } cannam@0: 00466 cannam@0: 00467 unsigned int cannam@0: 00468 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle) cannam@0: 00469 { cannam@0: 00470 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00471 std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl; cannam@0: 00472 #endif cannam@0: 00473 cannam@0: 00474 return ((Plugin *)handle)->getMinChannelCount(); cannam@0: 00475 } cannam@0: 00476 cannam@0: 00477 unsigned int cannam@0: 00478 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle) cannam@0: 00479 { cannam@0: 00480 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00481 std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl; cannam@0: 00482 #endif cannam@0: 00483 cannam@0: 00484 return ((Plugin *)handle)->getMaxChannelCount(); cannam@0: 00485 } cannam@0: 00486 cannam@0: 00487 unsigned int cannam@0: 00488 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle) cannam@0: 00489 { cannam@0: 00490 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00491 std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl; cannam@0: 00492 #endif cannam@0: 00493 cannam@0: 00494 Impl *adapter = lookupAdapter(handle); cannam@0: 00495 cannam@0: 00496 // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl; cannam@0: 00497 cannam@0: 00498 if (!adapter) return 0; cannam@0: 00499 return adapter->getOutputCount((Plugin *)handle); cannam@0: 00500 } cannam@0: 00501 cannam@0: 00502 VampOutputDescriptor * cannam@0: 00503 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle, cannam@0: 00504 unsigned int i) cannam@0: 00505 { cannam@0: 00506 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00507 std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl; cannam@0: 00508 #endif cannam@0: 00509 cannam@0: 00510 Impl *adapter = lookupAdapter(handle); cannam@0: 00511 cannam@0: 00512 // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl; cannam@0: 00513 cannam@0: 00514 if (!adapter) return 0; cannam@0: 00515 return adapter->getOutputDescriptor((Plugin *)handle, i); cannam@0: 00516 } cannam@0: 00517 cannam@0: 00518 void cannam@0: 00519 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc) cannam@0: 00520 { cannam@0: 00521 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00522 std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl; cannam@0: 00523 #endif cannam@0: 00524 cannam@0: 00525 if (desc->identifier) free((void *)desc->identifier); cannam@0: 00526 if (desc->name) free((void *)desc->name); cannam@0: 00527 if (desc->description) free((void *)desc->description); cannam@0: 00528 if (desc->unit) free((void *)desc->unit); cannam@0: 00529 if (desc->hasFixedBinCount && desc->binNames) { cannam@0: 00530 for (unsigned int i = 0; i < desc->binCount; ++i) { cannam@0: 00531 if (desc->binNames[i]) { cannam@0: 00532 free((void *)desc->binNames[i]); cannam@0: 00533 } cannam@0: 00534 } cannam@0: 00535 } cannam@0: 00536 if (desc->binNames) free((void *)desc->binNames); cannam@0: 00537 free((void *)desc); cannam@0: 00538 } cannam@0: 00539 cannam@0: 00540 VampFeatureList * cannam@0: 00541 PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle, cannam@0: 00542 const float *const *inputBuffers, cannam@0: 00543 int sec, cannam@0: 00544 int nsec) cannam@0: 00545 { cannam@0: 00546 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00547 std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl; cannam@0: 00548 #endif cannam@0: 00549 cannam@0: 00550 Impl *adapter = lookupAdapter(handle); cannam@0: 00551 if (!adapter) return 0; cannam@0: 00552 return adapter->process((Plugin *)handle, cannam@0: 00553 inputBuffers, sec, nsec); cannam@0: 00554 } cannam@0: 00555 cannam@0: 00556 VampFeatureList * cannam@0: 00557 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle) cannam@0: 00558 { cannam@0: 00559 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00560 std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl; cannam@0: 00561 #endif cannam@0: 00562 cannam@0: 00563 Impl *adapter = lookupAdapter(handle); cannam@0: 00564 if (!adapter) return 0; cannam@0: 00565 return adapter->getRemainingFeatures((Plugin *)handle); cannam@0: 00566 } cannam@0: 00567 cannam@0: 00568 void cannam@0: 00569 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs) cannam@0: 00570 { cannam@0: 00571 #ifdef DEBUG_PLUGIN_ADAPTER cannam@0: 00572 std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl; cannam@0: 00573 #endif cannam@0: 00574 } cannam@0: 00575 cannam@0: 00576 void cannam@0: 00577 PluginAdapterBase::Impl::cleanup(Plugin *plugin) cannam@0: 00578 { cannam@0: 00579 if (m_fs.find(plugin) != m_fs.end()) { cannam@0: 00580 size_t outputCount = 0; cannam@0: 00581 if (m_pluginOutputs[plugin]) { cannam@0: 00582 outputCount = m_pluginOutputs[plugin]->size(); cannam@0: 00583 } cannam@0: 00584 VampFeatureList *list = m_fs[plugin]; cannam@0: 00585 for (unsigned int i = 0; i < outputCount; ++i) { cannam@0: 00586 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) { cannam@0: 00587 if (list[i].features[j].label) { cannam@0: 00588 free(list[i].features[j].label); cannam@0: 00589 } cannam@0: 00590 if (list[i].features[j].values) { cannam@0: 00591 free(list[i].features[j].values); cannam@0: 00592 } cannam@0: 00593 } cannam@0: 00594 if (list[i].features) free(list[i].features); cannam@0: 00595 } cannam@0: 00596 m_fs.erase(plugin); cannam@0: 00597 m_fsizes.erase(plugin); cannam@0: 00598 m_fvsizes.erase(plugin); cannam@0: 00599 } cannam@0: 00600 cannam@0: 00601 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { cannam@0: 00602 delete m_pluginOutputs[plugin]; cannam@0: 00603 m_pluginOutputs.erase(plugin); cannam@0: 00604 } cannam@0: 00605 cannam@0: 00606 if (m_adapterMap) { cannam@0: 00607 m_adapterMap->erase(plugin); cannam@0: 00608 cannam@0: 00609 if (m_adapterMap->empty()) { cannam@0: 00610 delete m_adapterMap; cannam@0: 00611 m_adapterMap = 0; cannam@0: 00612 } cannam@0: 00613 } cannam@0: 00614 cannam@0: 00615 delete ((Plugin *)plugin); cannam@0: 00616 } cannam@0: 00617 cannam@0: 00618 void cannam@0: 00619 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin) cannam@0: 00620 { cannam@0: 00621 if (m_pluginOutputs.find(plugin) == m_pluginOutputs.end() || cannam@0: 00622 !m_pluginOutputs[plugin]) { cannam@0: 00623 m_pluginOutputs[plugin] = new Plugin::OutputList cannam@0: 00624 (plugin->getOutputDescriptors()); cannam@0: 00625 // std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl; cannam@0: 00626 } cannam@0: 00627 } cannam@0: 00628 cannam@0: 00629 unsigned int cannam@0: 00630 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin) cannam@0: 00631 { cannam@0: 00632 checkOutputMap(plugin); cannam@0: 00633 return m_pluginOutputs[plugin]->size(); cannam@0: 00634 } cannam@0: 00635 cannam@0: 00636 VampOutputDescriptor * cannam@0: 00637 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin, cannam@0: 00638 unsigned int i) cannam@0: 00639 { cannam@0: 00640 checkOutputMap(plugin); cannam@0: 00641 Plugin::OutputDescriptor &od = cannam@0: 00642 (*m_pluginOutputs[plugin])[i]; cannam@0: 00643 cannam@0: 00644 VampOutputDescriptor *desc = (VampOutputDescriptor *) cannam@0: 00645 malloc(sizeof(VampOutputDescriptor)); cannam@0: 00646 cannam@0: 00647 desc->identifier = strdup(od.identifier.c_str()); cannam@0: 00648 desc->name = strdup(od.name.c_str()); cannam@0: 00649 desc->description = strdup(od.description.c_str()); cannam@0: 00650 desc->unit = strdup(od.unit.c_str()); cannam@0: 00651 desc->hasFixedBinCount = od.hasFixedBinCount; cannam@0: 00652 desc->binCount = od.binCount; cannam@0: 00653 cannam@0: 00654 if (od.hasFixedBinCount && od.binCount > 0) { cannam@0: 00655 desc->binNames = (const char **) cannam@0: 00656 malloc(od.binCount * sizeof(const char *)); cannam@0: 00657 cannam@0: 00658 for (unsigned int i = 0; i < od.binCount; ++i) { cannam@0: 00659 if (i < od.binNames.size()) { cannam@0: 00660 desc->binNames[i] = strdup(od.binNames[i].c_str()); cannam@0: 00661 } else { cannam@0: 00662 desc->binNames[i] = 0; cannam@0: 00663 } cannam@0: 00664 } cannam@0: 00665 } else { cannam@0: 00666 desc->binNames = 0; cannam@0: 00667 } cannam@0: 00668 cannam@0: 00669 desc->hasKnownExtents = od.hasKnownExtents; cannam@0: 00670 desc->minValue = od.minValue; cannam@0: 00671 desc->maxValue = od.maxValue; cannam@0: 00672 desc->isQuantized = od.isQuantized; cannam@0: 00673 desc->quantizeStep = od.quantizeStep; cannam@0: 00674 cannam@0: 00675 switch (od.sampleType) { cannam@0: 00676 case Plugin::OutputDescriptor::OneSamplePerStep: cannam@0: 00677 desc->sampleType = vampOneSamplePerStep; break; cannam@0: 00678 case Plugin::OutputDescriptor::FixedSampleRate: cannam@0: 00679 desc->sampleType = vampFixedSampleRate; break; cannam@0: 00680 case Plugin::OutputDescriptor::VariableSampleRate: cannam@0: 00681 desc->sampleType = vampVariableSampleRate; break; cannam@0: 00682 } cannam@0: 00683 cannam@0: 00684 desc->sampleRate = od.sampleRate; cannam@0: 00685 cannam@0: 00686 return desc; cannam@0: 00687 } cannam@0: 00688 cannam@0: 00689 VampFeatureList * cannam@0: 00690 PluginAdapterBase::Impl::process(Plugin *plugin, cannam@0: 00691 const float *const *inputBuffers, cannam@0: 00692 int sec, int nsec) cannam@0: 00693 { cannam@0: 00694 // std::cerr << "PluginAdapterBase::Impl::process" << std::endl; cannam@0: 00695 RealTime rt(sec, nsec); cannam@0: 00696 checkOutputMap(plugin); cannam@0: 00697 return convertFeatures(plugin, plugin->process(inputBuffers, rt)); cannam@0: 00698 } cannam@0: 00699 cannam@0: 00700 VampFeatureList * cannam@0: 00701 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin) cannam@0: 00702 { cannam@0: 00703 // std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl; cannam@0: 00704 checkOutputMap(plugin); cannam@0: 00705 return convertFeatures(plugin, plugin->getRemainingFeatures()); cannam@0: 00706 } cannam@0: 00707 cannam@0: 00708 VampFeatureList * cannam@0: 00709 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin, cannam@0: 00710 const Plugin::FeatureSet &features) cannam@0: 00711 { cannam@0: 00712 int lastN = -1; cannam@0: 00713 cannam@0: 00714 int outputCount = 0; cannam@0: 00715 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size(); cannam@0: 00716 cannam@0: 00717 resizeFS(plugin, outputCount); cannam@0: 00718 VampFeatureList *fs = m_fs[plugin]; cannam@0: 00719 cannam@0: 00720 for (Plugin::FeatureSet::const_iterator fi = features.begin(); cannam@0: 00721 fi != features.end(); ++fi) { cannam@0: 00722 cannam@0: 00723 int n = fi->first; cannam@0: 00724 cannam@0: 00725 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl; cannam@0: 00726 cannam@0: 00727 if (n >= int(outputCount)) { cannam@0: 00728 std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl; cannam@0: 00729 continue; cannam@0: 00730 } cannam@0: 00731 cannam@0: 00732 if (n > lastN + 1) { cannam@0: 00733 for (int i = lastN + 1; i < n; ++i) { cannam@0: 00734 fs[i].featureCount = 0; cannam@0: 00735 } cannam@0: 00736 } cannam@0: 00737 cannam@0: 00738 const Plugin::FeatureList &fl = fi->second; cannam@0: 00739 cannam@0: 00740 size_t sz = fl.size(); cannam@0: 00741 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz); cannam@0: 00742 fs[n].featureCount = sz; cannam@0: 00743 cannam@0: 00744 for (size_t j = 0; j < sz; ++j) { cannam@0: 00745 cannam@0: 00746 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl; cannam@0: 00747 cannam@0: 00748 VampFeature *feature = &fs[n].features[j]; cannam@0: 00749 cannam@0: 00750 feature->hasTimestamp = fl[j].hasTimestamp; cannam@0: 00751 feature->sec = fl[j].timestamp.sec; cannam@0: 00752 feature->nsec = fl[j].timestamp.nsec; cannam@0: 00753 feature->valueCount = fl[j].values.size(); cannam@0: 00754 cannam@0: 00755 if (feature->label) free(feature->label); cannam@0: 00756 cannam@0: 00757 if (fl[j].label.empty()) { cannam@0: 00758 feature->label = 0; cannam@0: 00759 } else { cannam@0: 00760 feature->label = strdup(fl[j].label.c_str()); cannam@0: 00761 } cannam@0: 00762 cannam@0: 00763 if (feature->valueCount > m_fvsizes[plugin][n][j]) { cannam@0: 00764 resizeFV(plugin, n, j, feature->valueCount); cannam@0: 00765 } cannam@0: 00766 cannam@0: 00767 for (unsigned int k = 0; k < feature->valueCount; ++k) { cannam@0: 00768 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl; cannam@0: 00769 feature->values[k] = fl[j].values[k]; cannam@0: 00770 } cannam@0: 00771 } cannam@0: 00772 cannam@0: 00773 lastN = n; cannam@0: 00774 } cannam@0: 00775 cannam@0: 00776 if (lastN == -1) return 0; cannam@0: 00777 cannam@0: 00778 if (int(outputCount) > lastN + 1) { cannam@0: 00779 for (int i = lastN + 1; i < int(outputCount); ++i) { cannam@0: 00780 fs[i].featureCount = 0; cannam@0: 00781 } cannam@0: 00782 } cannam@0: 00783 cannam@0: 00784 return fs; cannam@0: 00785 } cannam@0: 00786 cannam@0: 00787 void cannam@0: 00788 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n) cannam@0: 00789 { cannam@0: 00790 // std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl; cannam@0: 00791 cannam@0: 00792 int i = m_fsizes[plugin].size(); cannam@0: 00793 if (i >= n) return; cannam@0: 00794 cannam@0: 00795 // std::cerr << "resizing from " << i << std::endl; cannam@0: 00796 cannam@0: 00797 m_fs[plugin] = (VampFeatureList *)realloc cannam@0: 00798 (m_fs[plugin], n * sizeof(VampFeatureList)); cannam@0: 00799 cannam@0: 00800 while (i < n) { cannam@0: 00801 m_fs[plugin][i].featureCount = 0; cannam@0: 00802 m_fs[plugin][i].features = 0; cannam@0: 00803 m_fsizes[plugin].push_back(0); cannam@0: 00804 m_fvsizes[plugin].push_back(std::vector<size_t>()); cannam@0: 00805 i++; cannam@0: 00806 } cannam@0: 00807 } cannam@0: 00808 cannam@0: 00809 void cannam@0: 00810 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz) cannam@0: 00811 { cannam@0: 00812 // std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", " cannam@0: 00813 // << sz << ")" << std::endl; cannam@0: 00814 cannam@0: 00815 size_t i = m_fsizes[plugin][n]; cannam@0: 00816 if (i >= sz) return; cannam@0: 00817 cannam@0: 00818 // std::cerr << "resizing from " << i << std::endl; cannam@0: 00819 cannam@0: 00820 m_fs[plugin][n].features = (VampFeature *)realloc cannam@0: 00821 (m_fs[plugin][n].features, sz * sizeof(VampFeature)); cannam@0: 00822 cannam@0: 00823 while (m_fsizes[plugin][n] < sz) { cannam@0: 00824 m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0; cannam@0: 00825 m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0; cannam@0: 00826 m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0; cannam@0: 00827 m_fvsizes[plugin][n].push_back(0); cannam@0: 00828 m_fsizes[plugin][n]++; cannam@0: 00829 } cannam@0: 00830 } cannam@0: 00831 cannam@0: 00832 void cannam@0: 00833 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz) cannam@0: 00834 { cannam@0: 00835 // std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", " cannam@0: 00836 // << j << ", " << sz << ")" << std::endl; cannam@0: 00837 cannam@0: 00838 size_t i = m_fvsizes[plugin][n][j]; cannam@0: 00839 if (i >= sz) return; cannam@0: 00840 cannam@0: 00841 // std::cerr << "resizing from " << i << std::endl; cannam@0: 00842 cannam@0: 00843 m_fs[plugin][n].features[j].values = (float *)realloc cannam@0: 00844 (m_fs[plugin][n].features[j].values, sz * sizeof(float)); cannam@0: 00845 cannam@0: 00846 m_fvsizes[plugin][n][j] = sz; cannam@0: 00847 } cannam@0: 00848 cannam@0: 00849 PluginAdapterBase::Impl::AdapterMap * cannam@0: 00850 PluginAdapterBase::Impl::m_adapterMap = 0; cannam@0: 00851 cannam@0: 00852 } cannam@0: 00853 cannam@0: