| cannam@3 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| cannam@3 | 2 | 
| cannam@3 | 3 /* | 
| cannam@3 | 4     Vamp | 
| cannam@3 | 5 | 
| cannam@3 | 6     An API for audio analysis and feature extraction plugins. | 
| cannam@3 | 7 | 
| cannam@3 | 8     Centre for Digital Music, Queen Mary, University of London. | 
| cannam@3 | 9     Copyright 2006 Chris Cannam. | 
| cannam@3 | 10 | 
| cannam@3 | 11     Permission is hereby granted, free of charge, to any person | 
| cannam@3 | 12     obtaining a copy of this software and associated documentation | 
| cannam@3 | 13     files (the "Software"), to deal in the Software without | 
| cannam@3 | 14     restriction, including without limitation the rights to use, copy, | 
| cannam@3 | 15     modify, merge, publish, distribute, sublicense, and/or sell copies | 
| cannam@3 | 16     of the Software, and to permit persons to whom the Software is | 
| cannam@3 | 17     furnished to do so, subject to the following conditions: | 
| cannam@3 | 18 | 
| cannam@3 | 19     The above copyright notice and this permission notice shall be | 
| cannam@3 | 20     included in all copies or substantial portions of the Software. | 
| cannam@3 | 21 | 
| cannam@3 | 22     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
| cannam@3 | 23     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
| cannam@3 | 24     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
| cannam@6 | 25     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR | 
| cannam@3 | 26     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | 
| cannam@3 | 27     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | 
| cannam@3 | 28     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 
| cannam@3 | 29 | 
| cannam@3 | 30     Except as contained in this notice, the names of the Centre for | 
| cannam@3 | 31     Digital Music; Queen Mary, University of London; and Chris Cannam | 
| cannam@3 | 32     shall not be used in advertising or otherwise to promote the sale, | 
| cannam@3 | 33     use or other dealings in this Software without prior written | 
| cannam@3 | 34     authorization. | 
| cannam@3 | 35 */ | 
| cannam@3 | 36 | 
| cannam@3 | 37 #include "PluginAdapter.h" | 
| cannam@3 | 38 | 
| cannam@23 | 39 //#define DEBUG_PLUGIN_ADAPTER 1 | 
| cannam@22 | 40 | 
| cannam@22 | 41 | 
| cannam@3 | 42 namespace Vamp { | 
| cannam@3 | 43 | 
| cannam@3 | 44 PluginAdapterBase::PluginAdapterBase() : | 
| cannam@3 | 45     m_populated(false) | 
| cannam@3 | 46 { | 
| cannam@22 | 47 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 48     std::cerr << "PluginAdapterBase[" << this << "]::PluginAdapterBase" << std::endl; | 
| cannam@22 | 49 #endif | 
| cannam@3 | 50 } | 
| cannam@3 | 51 | 
| cannam@3 | 52 const VampPluginDescriptor * | 
| cannam@3 | 53 PluginAdapterBase::getDescriptor() | 
| cannam@3 | 54 { | 
| cannam@22 | 55 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 56     std::cerr << "PluginAdapterBase[" << this << "]::getDescriptor" << std::endl; | 
| cannam@22 | 57 #endif | 
| cannam@22 | 58 | 
| cannam@3 | 59     if (m_populated) return &m_descriptor; | 
| cannam@3 | 60 | 
| cannam@3 | 61     Plugin *plugin = createPlugin(48000); | 
| cannam@3 | 62 | 
| cannam@3 | 63     m_parameters = plugin->getParameterDescriptors(); | 
| cannam@3 | 64     m_programs = plugin->getPrograms(); | 
| cannam@3 | 65 | 
| cannam@49 | 66     m_descriptor.identifier = strdup(plugin->getIdentifier().c_str()); | 
| cannam@3 | 67     m_descriptor.name = strdup(plugin->getName().c_str()); | 
| cannam@3 | 68     m_descriptor.description = strdup(plugin->getDescription().c_str()); | 
| cannam@3 | 69     m_descriptor.maker = strdup(plugin->getMaker().c_str()); | 
| cannam@3 | 70     m_descriptor.pluginVersion = plugin->getPluginVersion(); | 
| cannam@3 | 71     m_descriptor.copyright = strdup(plugin->getCopyright().c_str()); | 
| cannam@3 | 72 | 
| cannam@3 | 73     m_descriptor.parameterCount = m_parameters.size(); | 
| cannam@3 | 74     m_descriptor.parameters = (const VampParameterDescriptor **) | 
| cannam@3 | 75         malloc(m_parameters.size() * sizeof(VampParameterDescriptor)); | 
| cannam@7 | 76 | 
| cannam@7 | 77     unsigned int i; | 
| cannam@3 | 78 | 
| cannam@7 | 79     for (i = 0; i < m_parameters.size(); ++i) { | 
| cannam@3 | 80         VampParameterDescriptor *desc = (VampParameterDescriptor *) | 
| cannam@3 | 81             malloc(sizeof(VampParameterDescriptor)); | 
| cannam@49 | 82         desc->identifier = strdup(m_parameters[i].identifier.c_str()); | 
| cannam@3 | 83         desc->name = strdup(m_parameters[i].name.c_str()); | 
| cannam@3 | 84         desc->description = strdup(m_parameters[i].description.c_str()); | 
| cannam@3 | 85         desc->unit = strdup(m_parameters[i].unit.c_str()); | 
| cannam@3 | 86         desc->minValue = m_parameters[i].minValue; | 
| cannam@3 | 87         desc->maxValue = m_parameters[i].maxValue; | 
| cannam@3 | 88         desc->defaultValue = m_parameters[i].defaultValue; | 
| cannam@3 | 89         desc->isQuantized = m_parameters[i].isQuantized; | 
| cannam@3 | 90         desc->quantizeStep = m_parameters[i].quantizeStep; | 
| cannam@9 | 91         desc->valueNames = 0; | 
| cannam@9 | 92         if (desc->isQuantized && !m_parameters[i].valueNames.empty()) { | 
| cannam@9 | 93             desc->valueNames = (const char **) | 
| cannam@9 | 94                 malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *)); | 
| cannam@9 | 95             for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) { | 
| cannam@9 | 96                 desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str()); | 
| cannam@9 | 97             } | 
| cannam@9 | 98             desc->valueNames[m_parameters[i].valueNames.size()] = 0; | 
| cannam@9 | 99         } | 
| cannam@3 | 100         m_descriptor.parameters[i] = desc; | 
| cannam@3 | 101     } | 
| cannam@3 | 102 | 
| cannam@3 | 103     m_descriptor.programCount = m_programs.size(); | 
| cannam@3 | 104     m_descriptor.programs = (const char **) | 
| cannam@3 | 105         malloc(m_programs.size() * sizeof(const char *)); | 
| cannam@3 | 106 | 
| cannam@7 | 107     for (i = 0; i < m_programs.size(); ++i) { | 
| cannam@3 | 108         m_descriptor.programs[i] = strdup(m_programs[i].c_str()); | 
| cannam@3 | 109     } | 
| cannam@3 | 110 | 
| cannam@3 | 111     if (plugin->getInputDomain() == Plugin::FrequencyDomain) { | 
| cannam@3 | 112         m_descriptor.inputDomain = vampFrequencyDomain; | 
| cannam@3 | 113     } else { | 
| cannam@3 | 114         m_descriptor.inputDomain = vampTimeDomain; | 
| cannam@3 | 115     } | 
| cannam@3 | 116 | 
| cannam@3 | 117     m_descriptor.instantiate = vampInstantiate; | 
| cannam@3 | 118     m_descriptor.cleanup = vampCleanup; | 
| cannam@3 | 119     m_descriptor.initialise = vampInitialise; | 
| cannam@3 | 120     m_descriptor.reset = vampReset; | 
| cannam@3 | 121     m_descriptor.getParameter = vampGetParameter; | 
| cannam@3 | 122     m_descriptor.setParameter = vampSetParameter; | 
| cannam@3 | 123     m_descriptor.getCurrentProgram = vampGetCurrentProgram; | 
| cannam@3 | 124     m_descriptor.selectProgram = vampSelectProgram; | 
| cannam@3 | 125     m_descriptor.getPreferredStepSize = vampGetPreferredStepSize; | 
| cannam@3 | 126     m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize; | 
| cannam@3 | 127     m_descriptor.getMinChannelCount = vampGetMinChannelCount; | 
| cannam@3 | 128     m_descriptor.getMaxChannelCount = vampGetMaxChannelCount; | 
| cannam@3 | 129     m_descriptor.getOutputCount = vampGetOutputCount; | 
| cannam@3 | 130     m_descriptor.getOutputDescriptor = vampGetOutputDescriptor; | 
| cannam@3 | 131     m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor; | 
| cannam@3 | 132     m_descriptor.process = vampProcess; | 
| cannam@3 | 133     m_descriptor.getRemainingFeatures = vampGetRemainingFeatures; | 
| cannam@3 | 134     m_descriptor.releaseFeatureSet = vampReleaseFeatureSet; | 
| cannam@3 | 135 | 
| cannam@13 | 136     if (!m_adapterMap) { | 
| cannam@13 | 137         m_adapterMap = new AdapterMap; | 
| cannam@13 | 138     } | 
| cannam@15 | 139     (*m_adapterMap)[&m_descriptor] = this; | 
| cannam@3 | 140 | 
| cannam@3 | 141     delete plugin; | 
| cannam@3 | 142 | 
| cannam@3 | 143     m_populated = true; | 
| cannam@3 | 144     return &m_descriptor; | 
| cannam@3 | 145 } | 
| cannam@3 | 146 | 
| cannam@3 | 147 PluginAdapterBase::~PluginAdapterBase() | 
| cannam@3 | 148 { | 
| cannam@22 | 149 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 150     std::cerr << "PluginAdapterBase[" << this << "]::~PluginAdapterBase" << std::endl; | 
| cannam@22 | 151 #endif | 
| cannam@22 | 152 | 
| cannam@3 | 153     if (!m_populated) return; | 
| cannam@3 | 154 | 
| cannam@49 | 155     free((void *)m_descriptor.identifier); | 
| cannam@3 | 156     free((void *)m_descriptor.name); | 
| cannam@3 | 157     free((void *)m_descriptor.description); | 
| cannam@3 | 158     free((void *)m_descriptor.maker); | 
| cannam@3 | 159     free((void *)m_descriptor.copyright); | 
| cannam@3 | 160 | 
| cannam@3 | 161     for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) { | 
| cannam@3 | 162         const VampParameterDescriptor *desc = m_descriptor.parameters[i]; | 
| cannam@49 | 163         free((void *)desc->identifier); | 
| cannam@3 | 164         free((void *)desc->name); | 
| cannam@3 | 165         free((void *)desc->description); | 
| cannam@3 | 166         free((void *)desc->unit); | 
| cannam@9 | 167         if (desc->valueNames) { | 
| cannam@9 | 168             for (unsigned int j = 0; desc->valueNames[j]; ++j) { | 
| cannam@9 | 169                 free((void *)desc->valueNames[j]); | 
| cannam@9 | 170             } | 
| cannam@9 | 171             free((void *)desc->valueNames); | 
| cannam@9 | 172         } | 
| cannam@3 | 173     } | 
| cannam@3 | 174     free((void *)m_descriptor.parameters); | 
| cannam@3 | 175 | 
| cannam@3 | 176     for (unsigned int i = 0; i < m_descriptor.programCount; ++i) { | 
| cannam@3 | 177         free((void *)m_descriptor.programs[i]); | 
| cannam@3 | 178     } | 
| cannam@3 | 179     free((void *)m_descriptor.programs); | 
| cannam@3 | 180 | 
| cannam@13 | 181     if (m_adapterMap) { | 
| cannam@13 | 182 | 
| cannam@13 | 183         m_adapterMap->erase(&m_descriptor); | 
| cannam@13 | 184 | 
| cannam@13 | 185         if (m_adapterMap->empty()) { | 
| cannam@13 | 186             delete m_adapterMap; | 
| cannam@13 | 187             m_adapterMap = 0; | 
| cannam@13 | 188         } | 
| cannam@13 | 189     } | 
| cannam@3 | 190 } | 
| cannam@3 | 191 | 
| cannam@3 | 192 PluginAdapterBase * | 
| cannam@3 | 193 PluginAdapterBase::lookupAdapter(VampPluginHandle handle) | 
| cannam@3 | 194 { | 
| cannam@22 | 195 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 196     std::cerr << "PluginAdapterBase::lookupAdapter(" << handle << ")" << std::endl; | 
| cannam@22 | 197 #endif | 
| cannam@22 | 198 | 
| cannam@13 | 199     if (!m_adapterMap) return 0; | 
| cannam@13 | 200     AdapterMap::const_iterator i = m_adapterMap->find(handle); | 
| cannam@13 | 201     if (i == m_adapterMap->end()) return 0; | 
| cannam@3 | 202     return i->second; | 
| cannam@3 | 203 } | 
| cannam@3 | 204 | 
| cannam@3 | 205 VampPluginHandle | 
| cannam@3 | 206 PluginAdapterBase::vampInstantiate(const VampPluginDescriptor *desc, | 
| cannam@3 | 207                                    float inputSampleRate) | 
| cannam@3 | 208 { | 
| cannam@22 | 209 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 210     std::cerr << "PluginAdapterBase::vampInstantiate(" << desc << ")" << std::endl; | 
| cannam@22 | 211 #endif | 
| cannam@22 | 212 | 
| cannam@15 | 213     if (!m_adapterMap) { | 
| cannam@15 | 214         m_adapterMap = new AdapterMap(); | 
| cannam@15 | 215     } | 
| cannam@15 | 216 | 
| cannam@15 | 217     if (m_adapterMap->find(desc) == m_adapterMap->end()) { | 
| cannam@15 | 218         std::cerr << "WARNING: PluginAdapterBase::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl; | 
| cannam@15 | 219         return 0; | 
| cannam@15 | 220     } | 
| cannam@15 | 221 | 
| cannam@13 | 222     PluginAdapterBase *adapter = (*m_adapterMap)[desc]; | 
| cannam@3 | 223     if (desc != &adapter->m_descriptor) return 0; | 
| cannam@3 | 224 | 
| cannam@3 | 225     Plugin *plugin = adapter->createPlugin(inputSampleRate); | 
| cannam@3 | 226     if (plugin) { | 
| cannam@13 | 227         (*m_adapterMap)[plugin] = adapter; | 
| cannam@3 | 228     } | 
| cannam@3 | 229 | 
| cannam@22 | 230 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 231     std::cerr << "PluginAdapterBase::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl; | 
| cannam@22 | 232 #endif | 
| cannam@22 | 233 | 
| cannam@3 | 234     return plugin; | 
| cannam@3 | 235 } | 
| cannam@3 | 236 | 
| cannam@3 | 237 void | 
| cannam@3 | 238 PluginAdapterBase::vampCleanup(VampPluginHandle handle) | 
| cannam@3 | 239 { | 
| cannam@22 | 240 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 241     std::cerr << "PluginAdapterBase::vampCleanup(" << handle << ")" << std::endl; | 
| cannam@22 | 242 #endif | 
| cannam@22 | 243 | 
| cannam@3 | 244     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@3 | 245     if (!adapter) { | 
| cannam@3 | 246         delete ((Plugin *)handle); | 
| cannam@3 | 247         return; | 
| cannam@3 | 248     } | 
| cannam@3 | 249     adapter->cleanup(((Plugin *)handle)); | 
| cannam@3 | 250 } | 
| cannam@3 | 251 | 
| cannam@3 | 252 int | 
| cannam@3 | 253 PluginAdapterBase::vampInitialise(VampPluginHandle handle, | 
| cannam@3 | 254                                   unsigned int channels, | 
| cannam@3 | 255                                   unsigned int stepSize, | 
| cannam@3 | 256                                   unsigned int blockSize) | 
| cannam@3 | 257 { | 
| cannam@22 | 258 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 259     std::cerr << "PluginAdapterBase::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl; | 
| cannam@22 | 260 #endif | 
| cannam@22 | 261 | 
| cannam@3 | 262     bool result = ((Plugin *)handle)->initialise | 
| cannam@3 | 263         (channels, stepSize, blockSize); | 
| cannam@3 | 264     return result ? 1 : 0; | 
| cannam@3 | 265 } | 
| cannam@3 | 266 | 
| cannam@3 | 267 void | 
| cannam@3 | 268 PluginAdapterBase::vampReset(VampPluginHandle handle) | 
| cannam@3 | 269 { | 
| cannam@22 | 270 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 271     std::cerr << "PluginAdapterBase::vampReset(" << handle << ")" << std::endl; | 
| cannam@22 | 272 #endif | 
| cannam@22 | 273 | 
| cannam@3 | 274     ((Plugin *)handle)->reset(); | 
| cannam@3 | 275 } | 
| cannam@3 | 276 | 
| cannam@3 | 277 float | 
| cannam@3 | 278 PluginAdapterBase::vampGetParameter(VampPluginHandle handle, | 
| cannam@3 | 279                                     int param) | 
| cannam@3 | 280 { | 
| cannam@22 | 281 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 282     std::cerr << "PluginAdapterBase::vampGetParameter(" << handle << ", " << param << ")" << std::endl; | 
| cannam@22 | 283 #endif | 
| cannam@22 | 284 | 
| cannam@3 | 285     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@3 | 286     if (!adapter) return 0.0; | 
| cannam@3 | 287     Plugin::ParameterList &list = adapter->m_parameters; | 
| cannam@49 | 288     return ((Plugin *)handle)->getParameter(list[param].identifier); | 
| cannam@3 | 289 } | 
| cannam@3 | 290 | 
| cannam@3 | 291 void | 
| cannam@3 | 292 PluginAdapterBase::vampSetParameter(VampPluginHandle handle, | 
| cannam@3 | 293                                     int param, float value) | 
| cannam@3 | 294 { | 
| cannam@22 | 295 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 296     std::cerr << "PluginAdapterBase::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl; | 
| cannam@22 | 297 #endif | 
| cannam@22 | 298 | 
| cannam@3 | 299     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@3 | 300     if (!adapter) return; | 
| cannam@3 | 301     Plugin::ParameterList &list = adapter->m_parameters; | 
| cannam@49 | 302     ((Plugin *)handle)->setParameter(list[param].identifier, value); | 
| cannam@3 | 303 } | 
| cannam@3 | 304 | 
| cannam@3 | 305 unsigned int | 
| cannam@3 | 306 PluginAdapterBase::vampGetCurrentProgram(VampPluginHandle handle) | 
| cannam@3 | 307 { | 
| cannam@22 | 308 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 309     std::cerr << "PluginAdapterBase::vampGetCurrentProgram(" << handle << ")" << std::endl; | 
| cannam@22 | 310 #endif | 
| cannam@22 | 311 | 
| cannam@3 | 312     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@3 | 313     if (!adapter) return 0; | 
| cannam@3 | 314     Plugin::ProgramList &list = adapter->m_programs; | 
| cannam@3 | 315     std::string program = ((Plugin *)handle)->getCurrentProgram(); | 
| cannam@3 | 316     for (unsigned int i = 0; i < list.size(); ++i) { | 
| cannam@3 | 317         if (list[i] == program) return i; | 
| cannam@3 | 318     } | 
| cannam@3 | 319     return 0; | 
| cannam@3 | 320 } | 
| cannam@3 | 321 | 
| cannam@3 | 322 void | 
| cannam@3 | 323 PluginAdapterBase::vampSelectProgram(VampPluginHandle handle, | 
| cannam@3 | 324                                      unsigned int program) | 
| cannam@3 | 325 { | 
| cannam@22 | 326 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 327     std::cerr << "PluginAdapterBase::vampSelectProgram(" << handle << ", " << program << ")" << std::endl; | 
| cannam@22 | 328 #endif | 
| cannam@22 | 329 | 
| cannam@3 | 330     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@3 | 331     if (!adapter) return; | 
| cannam@3 | 332     Plugin::ProgramList &list = adapter->m_programs; | 
| cannam@3 | 333     ((Plugin *)handle)->selectProgram(list[program]); | 
| cannam@3 | 334 } | 
| cannam@3 | 335 | 
| cannam@3 | 336 unsigned int | 
| cannam@3 | 337 PluginAdapterBase::vampGetPreferredStepSize(VampPluginHandle handle) | 
| cannam@3 | 338 { | 
| cannam@22 | 339 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 340     std::cerr << "PluginAdapterBase::vampGetPreferredStepSize(" << handle << ")" << std::endl; | 
| cannam@22 | 341 #endif | 
| cannam@22 | 342 | 
| cannam@3 | 343     return ((Plugin *)handle)->getPreferredStepSize(); | 
| cannam@3 | 344 } | 
| cannam@3 | 345 | 
| cannam@3 | 346 unsigned int | 
| cannam@3 | 347 PluginAdapterBase::vampGetPreferredBlockSize(VampPluginHandle handle) | 
| cannam@3 | 348 { | 
| cannam@22 | 349 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 350     std::cerr << "PluginAdapterBase::vampGetPreferredBlockSize(" << handle << ")" << std::endl; | 
| cannam@22 | 351 #endif | 
| cannam@22 | 352 | 
| cannam@3 | 353     return ((Plugin *)handle)->getPreferredBlockSize(); | 
| cannam@3 | 354 } | 
| cannam@3 | 355 | 
| cannam@3 | 356 unsigned int | 
| cannam@3 | 357 PluginAdapterBase::vampGetMinChannelCount(VampPluginHandle handle) | 
| cannam@3 | 358 { | 
| cannam@22 | 359 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 360     std::cerr << "PluginAdapterBase::vampGetMinChannelCount(" << handle << ")" << std::endl; | 
| cannam@22 | 361 #endif | 
| cannam@22 | 362 | 
| cannam@3 | 363     return ((Plugin *)handle)->getMinChannelCount(); | 
| cannam@3 | 364 } | 
| cannam@3 | 365 | 
| cannam@3 | 366 unsigned int | 
| cannam@3 | 367 PluginAdapterBase::vampGetMaxChannelCount(VampPluginHandle handle) | 
| cannam@3 | 368 { | 
| cannam@22 | 369 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 370     std::cerr << "PluginAdapterBase::vampGetMaxChannelCount(" << handle << ")" << std::endl; | 
| cannam@22 | 371 #endif | 
| cannam@22 | 372 | 
| cannam@3 | 373     return ((Plugin *)handle)->getMaxChannelCount(); | 
| cannam@3 | 374 } | 
| cannam@3 | 375 | 
| cannam@3 | 376 unsigned int | 
| cannam@3 | 377 PluginAdapterBase::vampGetOutputCount(VampPluginHandle handle) | 
| cannam@3 | 378 { | 
| cannam@22 | 379 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 380     std::cerr << "PluginAdapterBase::vampGetOutputCount(" << handle << ")" << std::endl; | 
| cannam@22 | 381 #endif | 
| cannam@22 | 382 | 
| cannam@3 | 383     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@15 | 384 | 
| cannam@15 | 385 //    std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl; | 
| cannam@15 | 386 | 
| cannam@3 | 387     if (!adapter) return 0; | 
| cannam@3 | 388     return adapter->getOutputCount((Plugin *)handle); | 
| cannam@3 | 389 } | 
| cannam@3 | 390 | 
| cannam@3 | 391 VampOutputDescriptor * | 
| cannam@3 | 392 PluginAdapterBase::vampGetOutputDescriptor(VampPluginHandle handle, | 
| cannam@3 | 393                                            unsigned int i) | 
| cannam@3 | 394 { | 
| cannam@22 | 395 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 396     std::cerr << "PluginAdapterBase::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl; | 
| cannam@22 | 397 #endif | 
| cannam@22 | 398 | 
| cannam@3 | 399     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@15 | 400 | 
| cannam@15 | 401 //    std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl; | 
| cannam@15 | 402 | 
| cannam@3 | 403     if (!adapter) return 0; | 
| cannam@3 | 404     return adapter->getOutputDescriptor((Plugin *)handle, i); | 
| cannam@3 | 405 } | 
| cannam@3 | 406 | 
| cannam@3 | 407 void | 
| cannam@3 | 408 PluginAdapterBase::vampReleaseOutputDescriptor(VampOutputDescriptor *desc) | 
| cannam@3 | 409 { | 
| cannam@22 | 410 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 411     std::cerr << "PluginAdapterBase::vampReleaseOutputDescriptor(" << desc << ")" << std::endl; | 
| cannam@22 | 412 #endif | 
| cannam@22 | 413 | 
| cannam@49 | 414     if (desc->identifier) free((void *)desc->identifier); | 
| cannam@3 | 415     if (desc->name) free((void *)desc->name); | 
| cannam@3 | 416     if (desc->description) free((void *)desc->description); | 
| cannam@3 | 417     if (desc->unit) free((void *)desc->unit); | 
| cannam@40 | 418     if (desc->hasFixedBinCount && desc->binNames) { | 
| cannam@40 | 419         for (unsigned int i = 0; i < desc->binCount; ++i) { | 
| cannam@40 | 420             if (desc->binNames[i]) { | 
| cannam@40 | 421                 free((void *)desc->binNames[i]); | 
| cannam@40 | 422             } | 
| cannam@40 | 423         } | 
| cannam@3 | 424     } | 
| cannam@9 | 425     if (desc->binNames) free((void *)desc->binNames); | 
| cannam@3 | 426     free((void *)desc); | 
| cannam@3 | 427 } | 
| cannam@3 | 428 | 
| cannam@12 | 429 VampFeatureList * | 
| cannam@3 | 430 PluginAdapterBase::vampProcess(VampPluginHandle handle, | 
| cannam@47 | 431                                const float *const *inputBuffers, | 
| cannam@3 | 432                                int sec, | 
| cannam@3 | 433                                int nsec) | 
| cannam@3 | 434 { | 
| cannam@22 | 435 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 436     std::cerr << "PluginAdapterBase::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl; | 
| cannam@22 | 437 #endif | 
| cannam@22 | 438 | 
| cannam@3 | 439     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@3 | 440     if (!adapter) return 0; | 
| cannam@3 | 441     return adapter->process((Plugin *)handle, | 
| cannam@3 | 442                             inputBuffers, sec, nsec); | 
| cannam@3 | 443 } | 
| cannam@3 | 444 | 
| cannam@12 | 445 VampFeatureList * | 
| cannam@3 | 446 PluginAdapterBase::vampGetRemainingFeatures(VampPluginHandle handle) | 
| cannam@3 | 447 { | 
| cannam@22 | 448 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 449     std::cerr << "PluginAdapterBase::vampGetRemainingFeatures(" << handle << ")" << std::endl; | 
| cannam@22 | 450 #endif | 
| cannam@22 | 451 | 
| cannam@3 | 452     PluginAdapterBase *adapter = lookupAdapter(handle); | 
| cannam@3 | 453     if (!adapter) return 0; | 
| cannam@3 | 454     return adapter->getRemainingFeatures((Plugin *)handle); | 
| cannam@3 | 455 } | 
| cannam@3 | 456 | 
| cannam@3 | 457 void | 
| cannam@12 | 458 PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList *fs) | 
| cannam@3 | 459 { | 
| cannam@22 | 460 #ifdef DEBUG_PLUGIN_ADAPTER | 
| cannam@22 | 461     std::cerr << "PluginAdapterBase::vampReleaseFeatureSet" << std::endl; | 
| cannam@22 | 462 #endif | 
| cannam@3 | 463 } | 
| cannam@3 | 464 | 
| cannam@3 | 465 void | 
| cannam@3 | 466 PluginAdapterBase::cleanup(Plugin *plugin) | 
| cannam@3 | 467 { | 
| cannam@12 | 468     if (m_fs.find(plugin) != m_fs.end()) { | 
| cannam@12 | 469         size_t outputCount = 0; | 
| cannam@12 | 470         if (m_pluginOutputs[plugin]) { | 
| cannam@12 | 471             outputCount = m_pluginOutputs[plugin]->size(); | 
| cannam@12 | 472         } | 
| cannam@12 | 473         VampFeatureList *list = m_fs[plugin]; | 
| cannam@12 | 474         for (unsigned int i = 0; i < outputCount; ++i) { | 
| cannam@12 | 475             for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) { | 
| cannam@12 | 476                 if (list[i].features[j].label) { | 
| cannam@12 | 477                     free(list[i].features[j].label); | 
| cannam@12 | 478                 } | 
| cannam@12 | 479                 if (list[i].features[j].values) { | 
| cannam@12 | 480                     free(list[i].features[j].values); | 
| cannam@12 | 481                 } | 
| cannam@12 | 482             } | 
| cannam@12 | 483             if (list[i].features) free(list[i].features); | 
| cannam@12 | 484         } | 
| cannam@12 | 485         m_fs.erase(plugin); | 
| cannam@12 | 486         m_fsizes.erase(plugin); | 
| cannam@12 | 487         m_fvsizes.erase(plugin); | 
| cannam@12 | 488     } | 
| cannam@12 | 489 | 
| cannam@3 | 490     if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { | 
| cannam@3 | 491         delete m_pluginOutputs[plugin]; | 
| cannam@3 | 492         m_pluginOutputs.erase(plugin); | 
| cannam@3 | 493     } | 
| cannam@13 | 494 | 
| cannam@13 | 495     if (m_adapterMap) { | 
| cannam@13 | 496         m_adapterMap->erase(plugin); | 
| cannam@13 | 497 | 
| cannam@13 | 498         if (m_adapterMap->empty()) { | 
| cannam@13 | 499             delete m_adapterMap; | 
| cannam@13 | 500             m_adapterMap = 0; | 
| cannam@13 | 501         } | 
| cannam@13 | 502     } | 
| cannam@13 | 503 | 
| cannam@3 | 504     delete ((Plugin *)plugin); | 
| cannam@3 | 505 } | 
| cannam@3 | 506 | 
| cannam@3 | 507 void | 
| cannam@3 | 508 PluginAdapterBase::checkOutputMap(Plugin *plugin) | 
| cannam@3 | 509 { | 
| cannam@15 | 510     if (m_pluginOutputs.find(plugin) == m_pluginOutputs.end() || | 
| cannam@15 | 511         !m_pluginOutputs[plugin]) { | 
| cannam@3 | 512         m_pluginOutputs[plugin] = new Plugin::OutputList | 
| cannam@3 | 513             (plugin->getOutputDescriptors()); | 
| cannam@49 | 514 //        std::cerr << "PluginAdapterBase::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl; | 
| cannam@3 | 515     } | 
| cannam@3 | 516 } | 
| cannam@3 | 517 | 
| cannam@3 | 518 unsigned int | 
| cannam@3 | 519 PluginAdapterBase::getOutputCount(Plugin *plugin) | 
| cannam@3 | 520 { | 
| cannam@3 | 521     checkOutputMap(plugin); | 
| cannam@3 | 522     return m_pluginOutputs[plugin]->size(); | 
| cannam@3 | 523 } | 
| cannam@3 | 524 | 
| cannam@3 | 525 VampOutputDescriptor * | 
| cannam@3 | 526 PluginAdapterBase::getOutputDescriptor(Plugin *plugin, | 
| cannam@3 | 527                                        unsigned int i) | 
| cannam@3 | 528 { | 
| cannam@3 | 529     checkOutputMap(plugin); | 
| cannam@3 | 530     Plugin::OutputDescriptor &od = | 
| cannam@3 | 531         (*m_pluginOutputs[plugin])[i]; | 
| cannam@3 | 532 | 
| cannam@3 | 533     VampOutputDescriptor *desc = (VampOutputDescriptor *) | 
| cannam@3 | 534         malloc(sizeof(VampOutputDescriptor)); | 
| cannam@3 | 535 | 
| cannam@49 | 536     desc->identifier = strdup(od.identifier.c_str()); | 
| cannam@3 | 537     desc->name = strdup(od.name.c_str()); | 
| cannam@3 | 538     desc->description = strdup(od.description.c_str()); | 
| cannam@3 | 539     desc->unit = strdup(od.unit.c_str()); | 
| cannam@9 | 540     desc->hasFixedBinCount = od.hasFixedBinCount; | 
| cannam@9 | 541     desc->binCount = od.binCount; | 
| cannam@3 | 542 | 
| cannam@9 | 543     if (od.hasFixedBinCount && od.binCount > 0) { | 
| cannam@9 | 544         desc->binNames = (const char **) | 
| cannam@9 | 545             malloc(od.binCount * sizeof(const char *)); | 
| cannam@3 | 546 | 
| cannam@9 | 547         for (unsigned int i = 0; i < od.binCount; ++i) { | 
| cannam@9 | 548             if (i < od.binNames.size()) { | 
| cannam@9 | 549                 desc->binNames[i] = strdup(od.binNames[i].c_str()); | 
| cannam@7 | 550             } else { | 
| cannam@9 | 551                 desc->binNames[i] = 0; | 
| cannam@7 | 552             } | 
| cannam@3 | 553         } | 
| cannam@7 | 554     } else { | 
| cannam@9 | 555         desc->binNames = 0; | 
| cannam@3 | 556     } | 
| cannam@3 | 557 | 
| cannam@3 | 558     desc->hasKnownExtents = od.hasKnownExtents; | 
| cannam@3 | 559     desc->minValue = od.minValue; | 
| cannam@3 | 560     desc->maxValue = od.maxValue; | 
| cannam@3 | 561     desc->isQuantized = od.isQuantized; | 
| cannam@3 | 562     desc->quantizeStep = od.quantizeStep; | 
| cannam@3 | 563 | 
| cannam@3 | 564     switch (od.sampleType) { | 
| cannam@3 | 565     case Plugin::OutputDescriptor::OneSamplePerStep: | 
| cannam@3 | 566         desc->sampleType = vampOneSamplePerStep; break; | 
| cannam@3 | 567     case Plugin::OutputDescriptor::FixedSampleRate: | 
| cannam@3 | 568         desc->sampleType = vampFixedSampleRate; break; | 
| cannam@3 | 569     case Plugin::OutputDescriptor::VariableSampleRate: | 
| cannam@3 | 570         desc->sampleType = vampVariableSampleRate; break; | 
| cannam@3 | 571     } | 
| cannam@3 | 572 | 
| cannam@3 | 573     desc->sampleRate = od.sampleRate; | 
| cannam@3 | 574 | 
| cannam@3 | 575     return desc; | 
| cannam@3 | 576 } | 
| cannam@3 | 577 | 
| cannam@12 | 578 VampFeatureList * | 
| cannam@3 | 579 PluginAdapterBase::process(Plugin *plugin, | 
| cannam@47 | 580                            const float *const *inputBuffers, | 
| cannam@3 | 581                            int sec, int nsec) | 
| cannam@3 | 582 { | 
| cannam@12 | 583 //    std::cerr << "PluginAdapterBase::process" << std::endl; | 
| cannam@3 | 584     RealTime rt(sec, nsec); | 
| cannam@12 | 585     checkOutputMap(plugin); | 
| cannam@12 | 586     return convertFeatures(plugin, plugin->process(inputBuffers, rt)); | 
| cannam@3 | 587 } | 
| cannam@3 | 588 | 
| cannam@12 | 589 VampFeatureList * | 
| cannam@3 | 590 PluginAdapterBase::getRemainingFeatures(Plugin *plugin) | 
| cannam@3 | 591 { | 
| cannam@12 | 592 //    std::cerr << "PluginAdapterBase::getRemainingFeatures" << std::endl; | 
| cannam@12 | 593     checkOutputMap(plugin); | 
| cannam@12 | 594     return convertFeatures(plugin, plugin->getRemainingFeatures()); | 
| cannam@3 | 595 } | 
| cannam@3 | 596 | 
| cannam@12 | 597 VampFeatureList * | 
| cannam@12 | 598 PluginAdapterBase::convertFeatures(Plugin *plugin, | 
| cannam@12 | 599                                    const Plugin::FeatureSet &features) | 
| cannam@3 | 600 { | 
| cannam@12 | 601     int lastN = -1; | 
| cannam@3 | 602 | 
| cannam@12 | 603     int outputCount = 0; | 
| cannam@12 | 604     if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size(); | 
| cannam@12 | 605 | 
| cannam@12 | 606     resizeFS(plugin, outputCount); | 
| cannam@12 | 607     VampFeatureList *fs = m_fs[plugin]; | 
| cannam@3 | 608 | 
| cannam@12 | 609     for (Plugin::FeatureSet::const_iterator fi = features.begin(); | 
| cannam@12 | 610          fi != features.end(); ++fi) { | 
| cannam@3 | 611 | 
| cannam@12 | 612         int n = fi->first; | 
| cannam@12 | 613 | 
| cannam@12 | 614 //        std::cerr << "PluginAdapterBase::convertFeatures: n = " << n << std::endl; | 
| cannam@7 | 615 | 
| cannam@12 | 616         if (n >= int(outputCount)) { | 
| cannam@12 | 617             std::cerr << "WARNING: PluginAdapterBase::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl; | 
| cannam@7 | 618             continue; | 
| cannam@7 | 619         } | 
| cannam@7 | 620 | 
| cannam@12 | 621         if (n > lastN + 1) { | 
| cannam@12 | 622             for (int i = lastN + 1; i < n; ++i) { | 
| cannam@12 | 623                 fs[i].featureCount = 0; | 
| cannam@12 | 624             } | 
| cannam@12 | 625         } | 
| cannam@7 | 626 | 
| cannam@7 | 627         const Plugin::FeatureList &fl = fi->second; | 
| cannam@7 | 628 | 
| cannam@12 | 629         size_t sz = fl.size(); | 
| cannam@12 | 630         if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz); | 
| cannam@12 | 631         fs[n].featureCount = sz; | 
| cannam@12 | 632 | 
| cannam@12 | 633         for (size_t j = 0; j < sz; ++j) { | 
| cannam@7 | 634 | 
| cannam@12 | 635 //            std::cerr << "PluginAdapterBase::convertFeatures: j = " << j << std::endl; | 
| cannam@7 | 636 | 
| cannam@12 | 637             VampFeature *feature = &fs[n].features[j]; | 
| cannam@7 | 638 | 
| cannam@7 | 639             feature->hasTimestamp = fl[j].hasTimestamp; | 
| cannam@7 | 640             feature->sec = fl[j].timestamp.sec; | 
| cannam@7 | 641             feature->nsec = fl[j].timestamp.nsec; | 
| cannam@7 | 642             feature->valueCount = fl[j].values.size(); | 
| cannam@7 | 643 | 
| cannam@12 | 644             if (feature->label) free(feature->label); | 
| cannam@12 | 645 | 
| cannam@12 | 646             if (fl[j].label.empty()) { | 
| cannam@12 | 647                 feature->label = 0; | 
| cannam@12 | 648             } else { | 
| cannam@12 | 649                 feature->label = strdup(fl[j].label.c_str()); | 
| cannam@7 | 650             } | 
| cannam@7 | 651 | 
| cannam@12 | 652             if (feature->valueCount > m_fvsizes[plugin][n][j]) { | 
| cannam@12 | 653                 resizeFV(plugin, n, j, feature->valueCount); | 
| cannam@12 | 654             } | 
| cannam@7 | 655 | 
| cannam@7 | 656             for (unsigned int k = 0; k < feature->valueCount; ++k) { | 
| cannam@12 | 657 //                std::cerr << "PluginAdapterBase::convertFeatures: k = " << k << std::endl; | 
| cannam@7 | 658                 feature->values[k] = fl[j].values[k]; | 
| cannam@3 | 659             } | 
| cannam@3 | 660         } | 
| cannam@12 | 661 | 
| cannam@12 | 662         lastN = n; | 
| cannam@3 | 663     } | 
| cannam@3 | 664 | 
| cannam@12 | 665     if (lastN == -1) return 0; | 
| cannam@12 | 666 | 
| cannam@12 | 667     if (int(outputCount) > lastN + 1) { | 
| cannam@12 | 668         for (int i = lastN + 1; i < int(outputCount); ++i) { | 
| cannam@12 | 669             fs[i].featureCount = 0; | 
| cannam@12 | 670         } | 
| cannam@12 | 671     } | 
| cannam@3 | 672 | 
| cannam@3 | 673     return fs; | 
| cannam@3 | 674 } | 
| cannam@3 | 675 | 
| cannam@12 | 676 void | 
| cannam@12 | 677 PluginAdapterBase::resizeFS(Plugin *plugin, int n) | 
| cannam@12 | 678 { | 
| cannam@12 | 679 //    std::cerr << "PluginAdapterBase::resizeFS(" << plugin << ", " << n << ")" << std::endl; | 
| cannam@12 | 680 | 
| cannam@12 | 681     int i = m_fsizes[plugin].size(); | 
| cannam@12 | 682     if (i >= n) return; | 
| cannam@12 | 683 | 
| cannam@16 | 684 //    std::cerr << "resizing from " << i << std::endl; | 
| cannam@12 | 685 | 
| cannam@12 | 686     m_fs[plugin] = (VampFeatureList *)realloc | 
| cannam@12 | 687         (m_fs[plugin], n * sizeof(VampFeatureList)); | 
| cannam@12 | 688 | 
| cannam@12 | 689     while (i < n) { | 
| cannam@12 | 690         m_fs[plugin][i].featureCount = 0; | 
| cannam@12 | 691         m_fs[plugin][i].features = 0; | 
| cannam@12 | 692         m_fsizes[plugin].push_back(0); | 
| cannam@12 | 693         m_fvsizes[plugin].push_back(std::vector<size_t>()); | 
| cannam@12 | 694         i++; | 
| cannam@12 | 695     } | 
| cannam@12 | 696 } | 
| cannam@12 | 697 | 
| cannam@12 | 698 void | 
| cannam@12 | 699 PluginAdapterBase::resizeFL(Plugin *plugin, int n, size_t sz) | 
| cannam@12 | 700 { | 
| cannam@16 | 701 //    std::cerr << "PluginAdapterBase::resizeFL(" << plugin << ", " << n << ", " | 
| cannam@16 | 702 //              << sz << ")" << std::endl; | 
| cannam@12 | 703 | 
| cannam@12 | 704     size_t i = m_fsizes[plugin][n]; | 
| cannam@12 | 705     if (i >= sz) return; | 
| cannam@12 | 706 | 
| cannam@16 | 707 //    std::cerr << "resizing from " << i << std::endl; | 
| cannam@12 | 708 | 
| cannam@12 | 709     m_fs[plugin][n].features = (VampFeature *)realloc | 
| cannam@12 | 710         (m_fs[plugin][n].features, sz * sizeof(VampFeature)); | 
| cannam@12 | 711 | 
| cannam@12 | 712     while (m_fsizes[plugin][n] < sz) { | 
| cannam@12 | 713         m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0; | 
| cannam@12 | 714         m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0; | 
| cannam@12 | 715         m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0; | 
| cannam@12 | 716         m_fvsizes[plugin][n].push_back(0); | 
| cannam@12 | 717         m_fsizes[plugin][n]++; | 
| cannam@12 | 718     } | 
| cannam@12 | 719 } | 
| cannam@12 | 720 | 
| cannam@12 | 721 void | 
| cannam@12 | 722 PluginAdapterBase::resizeFV(Plugin *plugin, int n, int j, size_t sz) | 
| cannam@12 | 723 { | 
| cannam@16 | 724 //    std::cerr << "PluginAdapterBase::resizeFV(" << plugin << ", " << n << ", " | 
| cannam@16 | 725 //              << j << ", " << sz << ")" << std::endl; | 
| cannam@12 | 726 | 
| cannam@12 | 727     size_t i = m_fvsizes[plugin][n][j]; | 
| cannam@12 | 728     if (i >= sz) return; | 
| cannam@12 | 729 | 
| cannam@16 | 730 //    std::cerr << "resizing from " << i << std::endl; | 
| cannam@12 | 731 | 
| cannam@12 | 732     m_fs[plugin][n].features[j].values = (float *)realloc | 
| cannam@12 | 733         (m_fs[plugin][n].features[j].values, sz * sizeof(float)); | 
| cannam@12 | 734 | 
| cannam@12 | 735     m_fvsizes[plugin][n][j] = sz; | 
| cannam@12 | 736 } | 
| cannam@12 | 737 | 
| cannam@13 | 738 PluginAdapterBase::AdapterMap * | 
| cannam@13 | 739 PluginAdapterBase::m_adapterMap = 0; | 
| cannam@3 | 740 | 
| cannam@3 | 741 } | 
| cannam@3 | 742 |