PluginAdapter.cpp

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

Generated on Thu Jun 19 13:34:02 2008 for VampPluginSDK by  doxygen 1.5.5