comparison src/vamp-sdk/PluginAdapter.cpp @ 532:569fc23fa37a

Merge from branch c++11-mutex
author Chris Cannam
date Tue, 22 Oct 2019 12:23:53 +0100
parents db2cd87cef6f
children 15a89a89aa9b
comparison
equal deleted inserted replaced
522:0b6802e3b755 532:569fc23fa37a
37 #include <vamp-sdk/PluginAdapter.h> 37 #include <vamp-sdk/PluginAdapter.h>
38 38
39 #include <cstring> 39 #include <cstring>
40 #include <cstdlib> 40 #include <cstdlib>
41 41
42 #if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 8 ) 42 #include <mutex>
43
44 #if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 9 )
43 #error Unexpected version of Vamp SDK header included 45 #error Unexpected version of Vamp SDK header included
44 #endif 46 #endif
45 47
48 using std::map;
49 using std::vector;
50 using std::string;
51 using std::cerr;
52 using std::endl;
53 using std::mutex;
54 using std::lock_guard;
46 55
47 //#define DEBUG_PLUGIN_ADAPTER 1 56 //#define DEBUG_PLUGIN_ADAPTER 1
48 57
49 _VAMP_SDK_PLUGSPACE_BEGIN(PluginAdapter.cpp) 58 _VAMP_SDK_PLUGSPACE_BEGIN(PluginAdapter.cpp)
50 59
101 void checkOutputMap(Plugin *plugin); 110 void checkOutputMap(Plugin *plugin);
102 void markOutputsChanged(Plugin *plugin); 111 void markOutputsChanged(Plugin *plugin);
103 112
104 void cleanup(Plugin *plugin); 113 void cleanup(Plugin *plugin);
105 unsigned int getOutputCount(Plugin *plugin); 114 unsigned int getOutputCount(Plugin *plugin);
106 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin, 115 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin, unsigned int i);
107 unsigned int i);
108 VampFeatureList *process(Plugin *plugin, 116 VampFeatureList *process(Plugin *plugin,
109 const float *const *inputBuffers, 117 const float *const *inputBuffers,
110 int sec, int nsec); 118 int sec, int nsec);
111 VampFeatureList *getRemainingFeatures(Plugin *plugin); 119 VampFeatureList *getRemainingFeatures(Plugin *plugin);
112 VampFeatureList *convertFeatures(Plugin *plugin, 120 VampFeatureList *convertFeatures(Plugin *plugin,
113 const Plugin::FeatureSet &features); 121 const Plugin::FeatureSet &features);
114 122
115 // maps both plugins and descriptors to adapters 123 // maps both plugins and descriptors to adapters
116 typedef std::map<const void *, Impl *> AdapterMap; 124 typedef map<const void *, Impl *> AdapterMap;
125
117 static AdapterMap *m_adapterMap; 126 static AdapterMap *m_adapterMap;
127
128 static mutex &adapterMapMutex() {
129 // If this mutex was a global static, then it might be
130 // destroyed before the last adapter, and we would end up
131 // trying to lock an invalid mutex when removing an adapter
132 // from the adapter map. To ensure it outlasts the adapters,
133 // we need to ensure it is constructed before the construction
134 // of any of them is complete, since destruction order is
135 // reverse of construction. So we have to make sure this is
136 // called from the PluginAdapterBase::Impl constructor below.
137 static mutex m;
138 return m;
139 }
140
118 static Impl *lookupAdapter(VampPluginHandle); 141 static Impl *lookupAdapter(VampPluginHandle);
119 142
143 mutex m_mutex; // guards all of the below
144
120 bool m_populated; 145 bool m_populated;
121 VampPluginDescriptor m_descriptor; 146 VampPluginDescriptor m_descriptor;
122 Plugin::ParameterList m_parameters; 147 Plugin::ParameterList m_parameters;
123 Plugin::ProgramList m_programs; 148 Plugin::ProgramList m_programs;
124 149
125 typedef std::map<Plugin *, Plugin::OutputList *> OutputMap; 150 typedef map<Plugin *, Plugin::OutputList *> OutputMap;
126 OutputMap m_pluginOutputs; 151 OutputMap m_pluginOutputs;
127 152
128 std::map<Plugin *, VampFeatureList *> m_fs; 153 map<Plugin *, VampFeatureList *> m_fs;
129 std::map<Plugin *, std::vector<size_t> > m_fsizes; 154 map<Plugin *, vector<size_t> > m_fsizes;
130 std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes; 155 map<Plugin *, vector<vector<size_t> > > m_fvsizes;
131 void resizeFS(Plugin *plugin, int n); 156 void resizeFS(Plugin *plugin, int n);
132 void resizeFL(Plugin *plugin, int n, size_t sz); 157 void resizeFL(Plugin *plugin, int n, size_t sz);
133 void resizeFV(Plugin *plugin, int n, int j, size_t sz); 158 void resizeFV(Plugin *plugin, int n, int j, size_t sz);
134 }; 159 };
135 160
152 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) : 177 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) :
153 m_base(base), 178 m_base(base),
154 m_populated(false) 179 m_populated(false)
155 { 180 {
156 #ifdef DEBUG_PLUGIN_ADAPTER 181 #ifdef DEBUG_PLUGIN_ADAPTER
157 std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl; 182 cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << endl;
158 #endif 183 #endif
184
185 (void)adapterMapMutex(); // see comment in adapterMapMutex function above
159 } 186 }
160 187
161 const VampPluginDescriptor * 188 const VampPluginDescriptor *
162 PluginAdapterBase::Impl::getDescriptor() 189 PluginAdapterBase::Impl::getDescriptor()
163 { 190 {
164 #ifdef DEBUG_PLUGIN_ADAPTER 191 #ifdef DEBUG_PLUGIN_ADAPTER
165 std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl; 192 cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << endl;
166 #endif 193 #endif
167 194
195 lock_guard<mutex> guard(m_mutex);
196
168 if (m_populated) return &m_descriptor; 197 if (m_populated) return &m_descriptor;
169 198
170 Plugin *plugin = m_base->createPlugin(48000); 199 Plugin *plugin = m_base->createPlugin(48000);
171 200
172 if (!plugin) { 201 if (!plugin) {
173 std::cerr << "PluginAdapterBase::Impl::getDescriptor: Failed to create plugin" << std::endl; 202 cerr << "PluginAdapterBase::Impl::getDescriptor: Failed to create plugin" << endl;
174 return 0; 203 return 0;
175 } 204 }
176 205
177 if (plugin->getVampApiVersion() != VAMP_API_VERSION) { 206 if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
178 std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: " 207 cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
179 << "API version " << plugin->getVampApiVersion() 208 << "API version " << plugin->getVampApiVersion()
180 << " for\nplugin \"" << plugin->getIdentifier() << "\" " 209 << " for\nplugin \"" << plugin->getIdentifier() << "\" "
181 << "differs from version " 210 << "differs from version "
182 << VAMP_API_VERSION << " for adapter.\n" 211 << VAMP_API_VERSION << " for adapter.\n"
183 << "This plugin is probably linked against a different version of the Vamp SDK\n" 212 << "This plugin is probably linked against a different version of the Vamp SDK\n"
184 << "from the version it was compiled with. It will need to be re-linked correctly\n" 213 << "from the version it was compiled with. It will need to be re-linked correctly\n"
185 << "before it can be used." << std::endl; 214 << "before it can be used." << endl;
186 delete plugin; 215 delete plugin;
187 return 0; 216 return 0;
188 } 217 }
189 218
190 m_parameters = plugin->getParameterDescriptors(); 219 m_parameters = plugin->getParameterDescriptors();
258 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor; 287 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor;
259 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor; 288 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor;
260 m_descriptor.process = vampProcess; 289 m_descriptor.process = vampProcess;
261 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures; 290 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
262 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet; 291 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
292
293 lock_guard<mutex> adapterMapGuard(adapterMapMutex());
263 294
264 if (!m_adapterMap) { 295 if (!m_adapterMap) {
265 m_adapterMap = new AdapterMap; 296 m_adapterMap = new AdapterMap;
266 } 297 }
267 (*m_adapterMap)[&m_descriptor] = this; 298 (*m_adapterMap)[&m_descriptor] = this;
273 } 304 }
274 305
275 PluginAdapterBase::Impl::~Impl() 306 PluginAdapterBase::Impl::~Impl()
276 { 307 {
277 #ifdef DEBUG_PLUGIN_ADAPTER 308 #ifdef DEBUG_PLUGIN_ADAPTER
278 std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl; 309 cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << endl;
279 #endif 310 #endif
311
312 lock_guard<mutex> guard(m_mutex);
280 313
281 if (!m_populated) return; 314 if (!m_populated) return;
282 315
283 free((void *)m_descriptor.identifier); 316 free((void *)m_descriptor.identifier);
284 free((void *)m_descriptor.name); 317 free((void *)m_descriptor.name);
305 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) { 338 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
306 free((void *)m_descriptor.programs[i]); 339 free((void *)m_descriptor.programs[i]);
307 } 340 }
308 free((void *)m_descriptor.programs); 341 free((void *)m_descriptor.programs);
309 342
343 lock_guard<mutex> adapterMapGuard(adapterMapMutex());
344
310 if (m_adapterMap) { 345 if (m_adapterMap) {
311 346
312 m_adapterMap->erase(&m_descriptor); 347 m_adapterMap->erase(&m_descriptor);
313 348
314 if (m_adapterMap->empty()) { 349 if (m_adapterMap->empty()) {
315 delete m_adapterMap; 350 delete m_adapterMap;
316 m_adapterMap = 0; 351 m_adapterMap = 0;
317 } 352 }
318 } 353 }
320 355
321 PluginAdapterBase::Impl * 356 PluginAdapterBase::Impl *
322 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle) 357 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle)
323 { 358 {
324 #ifdef DEBUG_PLUGIN_ADAPTER 359 #ifdef DEBUG_PLUGIN_ADAPTER
325 std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl; 360 cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << endl;
326 #endif 361 #endif
327 362
363 lock_guard<mutex> adapterMapGuard(adapterMapMutex());
364
328 if (!m_adapterMap) return 0; 365 if (!m_adapterMap) return 0;
329 AdapterMap::const_iterator i = m_adapterMap->find(handle); 366 AdapterMap::const_iterator i = m_adapterMap->find(handle);
330 if (i == m_adapterMap->end()) return 0; 367 if (i == m_adapterMap->end()) return 0;
331 return i->second; 368 return i->second;
332 } 369 }
334 VampPluginHandle 371 VampPluginHandle
335 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc, 372 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc,
336 float inputSampleRate) 373 float inputSampleRate)
337 { 374 {
338 #ifdef DEBUG_PLUGIN_ADAPTER 375 #ifdef DEBUG_PLUGIN_ADAPTER
339 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl; 376 cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << endl;
340 #endif 377 #endif
341 378
379 lock_guard<mutex> adapterMapGuard(adapterMapMutex());
380
342 if (!m_adapterMap) { 381 if (!m_adapterMap) {
343 m_adapterMap = new AdapterMap(); 382 m_adapterMap = new AdapterMap();
344 } 383 }
345 384
346 if (m_adapterMap->find(desc) == m_adapterMap->end()) { 385 if (m_adapterMap->find(desc) == m_adapterMap->end()) {
347 std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl; 386 cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << endl;
348 return 0; 387 return 0;
349 } 388 }
350 389
351 Impl *adapter = (*m_adapterMap)[desc]; 390 Impl *adapter = (*m_adapterMap)[desc];
352 if (desc != &adapter->m_descriptor) return 0; 391 if (desc != &adapter->m_descriptor) return 0;
355 if (plugin) { 394 if (plugin) {
356 (*m_adapterMap)[plugin] = adapter; 395 (*m_adapterMap)[plugin] = adapter;
357 } 396 }
358 397
359 #ifdef DEBUG_PLUGIN_ADAPTER 398 #ifdef DEBUG_PLUGIN_ADAPTER
360 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl; 399 cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << endl;
361 #endif 400 #endif
362 401
363 return plugin; 402 return plugin;
364 } 403 }
365 404
366 void 405 void
367 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle) 406 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle)
368 { 407 {
369 #ifdef DEBUG_PLUGIN_ADAPTER 408 #ifdef DEBUG_PLUGIN_ADAPTER
370 std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl; 409 cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << endl;
371 #endif 410 #endif
372 411
373 Impl *adapter = lookupAdapter(handle); 412 Impl *adapter = lookupAdapter(handle);
374 if (!adapter) { 413 if (!adapter) {
375 delete ((Plugin *)handle); 414 delete ((Plugin *)handle);
383 unsigned int channels, 422 unsigned int channels,
384 unsigned int stepSize, 423 unsigned int stepSize,
385 unsigned int blockSize) 424 unsigned int blockSize)
386 { 425 {
387 #ifdef DEBUG_PLUGIN_ADAPTER 426 #ifdef DEBUG_PLUGIN_ADAPTER
388 std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl; 427 cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << endl;
389 #endif 428 #endif
390 429
391 Impl *adapter = lookupAdapter(handle); 430 Impl *adapter = lookupAdapter(handle);
392 if (!adapter) return 0; 431 if (!adapter) return 0;
393 bool result = ((Plugin *)handle)->initialise(channels, stepSize, blockSize); 432 bool result = ((Plugin *)handle)->initialise(channels, stepSize, blockSize);
397 436
398 void 437 void
399 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle) 438 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle)
400 { 439 {
401 #ifdef DEBUG_PLUGIN_ADAPTER 440 #ifdef DEBUG_PLUGIN_ADAPTER
402 std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl; 441 cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << endl;
403 #endif 442 #endif
404 443
405 ((Plugin *)handle)->reset(); 444 ((Plugin *)handle)->reset();
406 } 445 }
407 446
408 float 447 float
409 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle, 448 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle,
410 int param) 449 int param)
411 { 450 {
412 #ifdef DEBUG_PLUGIN_ADAPTER 451 #ifdef DEBUG_PLUGIN_ADAPTER
413 std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl; 452 cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << endl;
414 #endif 453 #endif
415 454
416 Impl *adapter = lookupAdapter(handle); 455 Impl *adapter = lookupAdapter(handle);
417 if (!adapter) return 0.0; 456 if (!adapter) return 0.0;
418 Plugin::ParameterList &list = adapter->m_parameters; 457 Plugin::ParameterList &list = adapter->m_parameters;
422 void 461 void
423 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle, 462 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle,
424 int param, float value) 463 int param, float value)
425 { 464 {
426 #ifdef DEBUG_PLUGIN_ADAPTER 465 #ifdef DEBUG_PLUGIN_ADAPTER
427 std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl; 466 cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << endl;
428 #endif 467 #endif
429 468
430 Impl *adapter = lookupAdapter(handle); 469 Impl *adapter = lookupAdapter(handle);
431 if (!adapter) return; 470 if (!adapter) return;
432 Plugin::ParameterList &list = adapter->m_parameters; 471 Plugin::ParameterList &list = adapter->m_parameters;
436 475
437 unsigned int 476 unsigned int
438 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle) 477 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle)
439 { 478 {
440 #ifdef DEBUG_PLUGIN_ADAPTER 479 #ifdef DEBUG_PLUGIN_ADAPTER
441 std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl; 480 cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << endl;
442 #endif 481 #endif
443 482
444 Impl *adapter = lookupAdapter(handle); 483 Impl *adapter = lookupAdapter(handle);
445 if (!adapter) return 0; 484 if (!adapter) return 0;
446 Plugin::ProgramList &list = adapter->m_programs; 485 Plugin::ProgramList &list = adapter->m_programs;
447 std::string program = ((Plugin *)handle)->getCurrentProgram(); 486 string program = ((Plugin *)handle)->getCurrentProgram();
448 for (unsigned int i = 0; i < list.size(); ++i) { 487 for (unsigned int i = 0; i < list.size(); ++i) {
449 if (list[i] == program) return i; 488 if (list[i] == program) return i;
450 } 489 }
451 return 0; 490 return 0;
452 } 491 }
454 void 493 void
455 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle, 494 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle,
456 unsigned int program) 495 unsigned int program)
457 { 496 {
458 #ifdef DEBUG_PLUGIN_ADAPTER 497 #ifdef DEBUG_PLUGIN_ADAPTER
459 std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl; 498 cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << endl;
460 #endif 499 #endif
461 500
462 Impl *adapter = lookupAdapter(handle); 501 Impl *adapter = lookupAdapter(handle);
463 if (!adapter) return; 502 if (!adapter) return;
464 503
470 509
471 unsigned int 510 unsigned int
472 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle) 511 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle)
473 { 512 {
474 #ifdef DEBUG_PLUGIN_ADAPTER 513 #ifdef DEBUG_PLUGIN_ADAPTER
475 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl; 514 cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << endl;
476 #endif 515 #endif
477 516
478 return ((Plugin *)handle)->getPreferredStepSize(); 517 return ((Plugin *)handle)->getPreferredStepSize();
479 } 518 }
480 519
481 unsigned int 520 unsigned int
482 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle) 521 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle)
483 { 522 {
484 #ifdef DEBUG_PLUGIN_ADAPTER 523 #ifdef DEBUG_PLUGIN_ADAPTER
485 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl; 524 cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << endl;
486 #endif 525 #endif
487 526
488 return ((Plugin *)handle)->getPreferredBlockSize(); 527 return ((Plugin *)handle)->getPreferredBlockSize();
489 } 528 }
490 529
491 unsigned int 530 unsigned int
492 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle) 531 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle)
493 { 532 {
494 #ifdef DEBUG_PLUGIN_ADAPTER 533 #ifdef DEBUG_PLUGIN_ADAPTER
495 std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl; 534 cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << endl;
496 #endif 535 #endif
497 536
498 return ((Plugin *)handle)->getMinChannelCount(); 537 return ((Plugin *)handle)->getMinChannelCount();
499 } 538 }
500 539
501 unsigned int 540 unsigned int
502 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle) 541 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle)
503 { 542 {
504 #ifdef DEBUG_PLUGIN_ADAPTER 543 #ifdef DEBUG_PLUGIN_ADAPTER
505 std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl; 544 cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << endl;
506 #endif 545 #endif
507 546
508 return ((Plugin *)handle)->getMaxChannelCount(); 547 return ((Plugin *)handle)->getMaxChannelCount();
509 } 548 }
510 549
511 unsigned int 550 unsigned int
512 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle) 551 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle)
513 { 552 {
514 #ifdef DEBUG_PLUGIN_ADAPTER 553 #ifdef DEBUG_PLUGIN_ADAPTER
515 std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl; 554 cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << endl;
516 #endif 555 #endif
517 556
518 Impl *adapter = lookupAdapter(handle); 557 Impl *adapter = lookupAdapter(handle);
519 558
520 // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl; 559 // cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << endl;
521 560
522 if (!adapter) return 0; 561 if (!adapter) return 0;
523 return adapter->getOutputCount((Plugin *)handle); 562 return adapter->getOutputCount((Plugin *)handle);
524 } 563 }
525 564
526 VampOutputDescriptor * 565 VampOutputDescriptor *
527 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle, 566 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle,
528 unsigned int i) 567 unsigned int i)
529 { 568 {
530 #ifdef DEBUG_PLUGIN_ADAPTER 569 #ifdef DEBUG_PLUGIN_ADAPTER
531 std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl; 570 cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << endl;
532 #endif 571 #endif
533 572
534 Impl *adapter = lookupAdapter(handle); 573 Impl *adapter = lookupAdapter(handle);
535 574
536 // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl; 575 // cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << endl;
537 576
538 if (!adapter) return 0; 577 if (!adapter) return 0;
539 return adapter->getOutputDescriptor((Plugin *)handle, i); 578 return adapter->getOutputDescriptor((Plugin *)handle, i);
540 } 579 }
541 580
542 void 581 void
543 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc) 582 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc)
544 { 583 {
545 #ifdef DEBUG_PLUGIN_ADAPTER 584 #ifdef DEBUG_PLUGIN_ADAPTER
546 std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl; 585 cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << endl;
547 #endif 586 #endif
548 587
549 if (desc->identifier) free((void *)desc->identifier); 588 if (desc->identifier) free((void *)desc->identifier);
550 if (desc->name) free((void *)desc->name); 589 if (desc->name) free((void *)desc->name);
551 if (desc->description) free((void *)desc->description); 590 if (desc->description) free((void *)desc->description);
566 const float *const *inputBuffers, 605 const float *const *inputBuffers,
567 int sec, 606 int sec,
568 int nsec) 607 int nsec)
569 { 608 {
570 #ifdef DEBUG_PLUGIN_ADAPTER 609 #ifdef DEBUG_PLUGIN_ADAPTER
571 std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl; 610 cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << endl;
572 #endif 611 #endif
573 612
574 Impl *adapter = lookupAdapter(handle); 613 Impl *adapter = lookupAdapter(handle);
575 if (!adapter) return 0; 614 if (!adapter) return 0;
576 return adapter->process((Plugin *)handle, inputBuffers, sec, nsec); 615 return adapter->process((Plugin *)handle, inputBuffers, sec, nsec);
578 617
579 VampFeatureList * 618 VampFeatureList *
580 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle) 619 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
581 { 620 {
582 #ifdef DEBUG_PLUGIN_ADAPTER 621 #ifdef DEBUG_PLUGIN_ADAPTER
583 std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl; 622 cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << endl;
584 #endif 623 #endif
585 624
586 Impl *adapter = lookupAdapter(handle); 625 Impl *adapter = lookupAdapter(handle);
587 if (!adapter) return 0; 626 if (!adapter) return 0;
588 return adapter->getRemainingFeatures((Plugin *)handle); 627 return adapter->getRemainingFeatures((Plugin *)handle);
590 629
591 void 630 void
592 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *) 631 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *)
593 { 632 {
594 #ifdef DEBUG_PLUGIN_ADAPTER 633 #ifdef DEBUG_PLUGIN_ADAPTER
595 std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl; 634 cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << endl;
596 #endif 635 #endif
597 } 636 }
598 637
599 void 638 void
600 PluginAdapterBase::Impl::cleanup(Plugin *plugin) 639 PluginAdapterBase::Impl::cleanup(Plugin *plugin)
601 { 640 {
641 // at this point no mutex is held
642
643 lock_guard<mutex> adapterMapGuard(adapterMapMutex());
644 lock_guard<mutex> guard(m_mutex);
645
602 if (m_fs.find(plugin) != m_fs.end()) { 646 if (m_fs.find(plugin) != m_fs.end()) {
603 size_t outputCount = 0; 647 size_t outputCount = 0;
604 if (m_pluginOutputs[plugin]) { 648 if (m_pluginOutputs[plugin]) {
605 outputCount = m_pluginOutputs[plugin]->size(); 649 outputCount = m_pluginOutputs[plugin]->size();
606 } 650 }
607 #ifdef DEBUG_PLUGIN_ADAPTER 651 #ifdef DEBUG_PLUGIN_ADAPTER
608 std::cerr << "PluginAdapterBase::Impl::cleanup: " << outputCount << " output(s)" << std::endl; 652 cerr << "PluginAdapterBase::Impl::cleanup: " << outputCount << " output(s)" << endl;
609 #endif 653 #endif
610 VampFeatureList *list = m_fs[plugin]; 654 VampFeatureList *list = m_fs[plugin];
611 for (unsigned int i = 0; i < outputCount; ++i) { 655 for (unsigned int i = 0; i < outputCount; ++i) {
612 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) { 656 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) {
613 if (list[i].features[j].v1.label) { 657 if (list[i].features[j].v1.label) {
643 } 687 }
644 688
645 void 689 void
646 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin) 690 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin)
647 { 691 {
692 // must be called with m_mutex held
693
648 OutputMap::iterator i = m_pluginOutputs.find(plugin); 694 OutputMap::iterator i = m_pluginOutputs.find(plugin);
649 695
650 if (i == m_pluginOutputs.end() || !i->second) { 696 if (i == m_pluginOutputs.end() || !i->second) {
651 697
652 m_pluginOutputs[plugin] = new Plugin::OutputList 698 m_pluginOutputs[plugin] = new Plugin::OutputList
653 (plugin->getOutputDescriptors()); 699 (plugin->getOutputDescriptors());
654 700
655 // std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl; 701 // cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << endl;
656 } 702 }
657 } 703 }
658 704
659 void 705 void
660 PluginAdapterBase::Impl::markOutputsChanged(Plugin *plugin) 706 PluginAdapterBase::Impl::markOutputsChanged(Plugin *plugin)
661 { 707 {
708 lock_guard<mutex> guard(m_mutex);
709
662 OutputMap::iterator i = m_pluginOutputs.find(plugin); 710 OutputMap::iterator i = m_pluginOutputs.find(plugin);
663 711
664 // std::cerr << "PluginAdapterBase::Impl::markOutputsChanged" << std::endl; 712 // cerr << "PluginAdapterBase::Impl::markOutputsChanged" << endl;
665 713
666 if (i != m_pluginOutputs.end()) { 714 if (i != m_pluginOutputs.end()) {
667 715
668 Plugin::OutputList *list = i->second; 716 Plugin::OutputList *list = i->second;
669 m_pluginOutputs.erase(i); 717 m_pluginOutputs.erase(i);
672 } 720 }
673 721
674 unsigned int 722 unsigned int
675 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin) 723 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin)
676 { 724 {
725 lock_guard<mutex> guard(m_mutex);
726
677 checkOutputMap(plugin); 727 checkOutputMap(plugin);
678 728
679 return m_pluginOutputs[plugin]->size(); 729 return m_pluginOutputs[plugin]->size();
680 } 730 }
681 731
682 VampOutputDescriptor * 732 VampOutputDescriptor *
683 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin, 733 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin,
684 unsigned int i) 734 unsigned int i)
685 { 735 {
736 lock_guard<mutex> guard(m_mutex);
737
686 checkOutputMap(plugin); 738 checkOutputMap(plugin);
687 739
688 Plugin::OutputDescriptor &od = 740 Plugin::OutputDescriptor &od =
689 (*m_pluginOutputs[plugin])[i]; 741 (*m_pluginOutputs[plugin])[i];
690 742
742 VampFeatureList * 794 VampFeatureList *
743 PluginAdapterBase::Impl::process(Plugin *plugin, 795 PluginAdapterBase::Impl::process(Plugin *plugin,
744 const float *const *inputBuffers, 796 const float *const *inputBuffers,
745 int sec, int nsec) 797 int sec, int nsec)
746 { 798 {
747 // std::cerr << "PluginAdapterBase::Impl::process" << std::endl; 799 // cerr << "PluginAdapterBase::Impl::process" << endl;
800
748 RealTime rt(sec, nsec); 801 RealTime rt(sec, nsec);
749 checkOutputMap(plugin); 802
803 // We don't want to hold the mutex during the actual process call,
804 // only while looking up the associated metadata
805 {
806 lock_guard<mutex> guard(m_mutex);
807 checkOutputMap(plugin);
808 }
809
750 return convertFeatures(plugin, plugin->process(inputBuffers, rt)); 810 return convertFeatures(plugin, plugin->process(inputBuffers, rt));
751 } 811 }
752 812
753 VampFeatureList * 813 VampFeatureList *
754 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin) 814 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin)
755 { 815 {
756 // std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl; 816 // cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << endl;
757 checkOutputMap(plugin); 817
818 // We don't want to hold the mutex during the actual call, only
819 // while looking up the associated metadata
820 {
821 lock_guard<mutex> guard(m_mutex);
822 checkOutputMap(plugin);
823 }
824
758 return convertFeatures(plugin, plugin->getRemainingFeatures()); 825 return convertFeatures(plugin, plugin->getRemainingFeatures());
759 } 826 }
760 827
761 VampFeatureList * 828 VampFeatureList *
762 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin, 829 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin,
763 const Plugin::FeatureSet &features) 830 const Plugin::FeatureSet &features)
764 { 831 {
832 lock_guard<mutex> guard(m_mutex);
833
765 int lastN = -1; 834 int lastN = -1;
766 835
767 int outputCount = 0; 836 int outputCount = 0;
768 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size(); 837 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size();
769 838
770 resizeFS(plugin, outputCount); 839 resizeFS(plugin, outputCount);
771 VampFeatureList *fs = m_fs[plugin]; 840 VampFeatureList *fs = m_fs[plugin];
772 841
773 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: sizeof(Feature) == " << sizeof(Plugin::Feature) << ", sizeof(VampFeature) == " << sizeof(VampFeature) << ", sizeof(VampFeatureList) == " << sizeof(VampFeatureList) << std::endl; 842 // cerr << "PluginAdapter(v2)::convertFeatures: NOTE: sizeof(Feature) == " << sizeof(Plugin::Feature) << ", sizeof(VampFeature) == " << sizeof(VampFeature) << ", sizeof(VampFeatureList) == " << sizeof(VampFeatureList) << endl;
774 843
775 for (Plugin::FeatureSet::const_iterator fi = features.begin(); 844 for (Plugin::FeatureSet::const_iterator fi = features.begin();
776 fi != features.end(); ++fi) { 845 fi != features.end(); ++fi) {
777 846
778 int n = fi->first; 847 int n = fi->first;
779 848
780 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl; 849 // cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << endl;
781 850
782 if (n >= int(outputCount)) { 851 if (n >= int(outputCount)) {
783 std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl; 852 cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << endl;
784 continue; 853 continue;
785 } 854 }
786 855
787 if (n > lastN + 1) { 856 if (n > lastN + 1) {
788 for (int i = lastN + 1; i < n; ++i) { 857 for (int i = lastN + 1; i < n; ++i) {
796 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz); 865 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz);
797 fs[n].featureCount = sz; 866 fs[n].featureCount = sz;
798 867
799 for (size_t j = 0; j < sz; ++j) { 868 for (size_t j = 0; j < sz; ++j) {
800 869
801 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl; 870 // cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << endl;
802 871
803 VampFeature *feature = &fs[n].features[j].v1; 872 VampFeature *feature = &fs[n].features[j].v1;
804 873
805 feature->hasTimestamp = fl[j].hasTimestamp; 874 feature->hasTimestamp = fl[j].hasTimestamp;
806 feature->sec = fl[j].timestamp.sec; 875 feature->sec = fl[j].timestamp.sec;
824 if (feature->valueCount > m_fvsizes[plugin][n][j]) { 893 if (feature->valueCount > m_fvsizes[plugin][n][j]) {
825 resizeFV(plugin, n, j, feature->valueCount); 894 resizeFV(plugin, n, j, feature->valueCount);
826 } 895 }
827 896
828 for (unsigned int k = 0; k < feature->valueCount; ++k) { 897 for (unsigned int k = 0; k < feature->valueCount; ++k) {
829 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl; 898 // cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << endl;
830 feature->values[k] = fl[j].values[k]; 899 feature->values[k] = fl[j].values[k];
831 } 900 }
832 } 901 }
833 902
834 lastN = n; 903 lastN = n;
840 for (int i = lastN + 1; i < int(outputCount); ++i) { 909 for (int i = lastN + 1; i < int(outputCount); ++i) {
841 fs[i].featureCount = 0; 910 fs[i].featureCount = 0;
842 } 911 }
843 } 912 }
844 913
845 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: have " << outputCount << " outputs" << std::endl; 914 // cerr << "PluginAdapter(v2)::convertFeatures: NOTE: have " << outputCount << " outputs" << endl;
846 // for (int i = 0; i < outputCount; ++i) { 915 // for (int i = 0; i < outputCount; ++i) {
847 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: output " << i << " has " << fs[i].featureCount << " features" << std::endl; 916 // cerr << "PluginAdapter(v2)::convertFeatures: NOTE: output " << i << " has " << fs[i].featureCount << " features" << endl;
848 // } 917 // }
849 918
850 919
851 return fs; 920 return fs;
852 } 921 }
853 922
854 void 923 void
855 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n) 924 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
856 { 925 {
857 #ifdef DEBUG_PLUGIN_ADAPTER 926 // called with m_mutex held
858 std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl; 927
928 #ifdef DEBUG_PLUGIN_ADAPTER
929 cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << endl;
859 #endif 930 #endif
860 931
861 int i = m_fsizes[plugin].size(); 932 int i = m_fsizes[plugin].size();
862 if (i >= n) return; 933 if (i >= n) return;
863 934
864 #ifdef DEBUG_PLUGIN_ADAPTER 935 #ifdef DEBUG_PLUGIN_ADAPTER
865 std::cerr << "resizing from " << i << std::endl; 936 cerr << "resizing from " << i << endl;
866 #endif 937 #endif
867 938
868 m_fs[plugin] = (VampFeatureList *)realloc 939 m_fs[plugin] = (VampFeatureList *)realloc
869 (m_fs[plugin], n * sizeof(VampFeatureList)); 940 (m_fs[plugin], n * sizeof(VampFeatureList));
870 941
871 while (i < n) { 942 while (i < n) {
872 m_fs[plugin][i].featureCount = 0; 943 m_fs[plugin][i].featureCount = 0;
873 m_fs[plugin][i].features = 0; 944 m_fs[plugin][i].features = 0;
874 m_fsizes[plugin].push_back(0); 945 m_fsizes[plugin].push_back(0);
875 m_fvsizes[plugin].push_back(std::vector<size_t>()); 946 m_fvsizes[plugin].push_back(vector<size_t>());
876 i++; 947 i++;
877 } 948 }
878 } 949 }
879 950
880 void 951 void
881 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz) 952 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
882 { 953 {
883 #ifdef DEBUG_PLUGIN_ADAPTER 954 // called with m_mutex held
884 std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", " 955
885 << sz << ")" << std::endl; 956 #ifdef DEBUG_PLUGIN_ADAPTER
957 cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
958 << sz << ")" << endl;
886 #endif 959 #endif
887 960
888 size_t i = m_fsizes[plugin][n]; 961 size_t i = m_fsizes[plugin][n];
889 if (i >= sz) return; 962 if (i >= sz) return;
890 963
891 #ifdef DEBUG_PLUGIN_ADAPTER 964 #ifdef DEBUG_PLUGIN_ADAPTER
892 std::cerr << "resizing from " << i << std::endl; 965 cerr << "resizing from " << i << endl;
893 #endif 966 #endif
894 967
895 m_fs[plugin][n].features = (VampFeatureUnion *)realloc 968 m_fs[plugin][n].features = (VampFeatureUnion *)realloc
896 (m_fs[plugin][n].features, 2 * sz * sizeof(VampFeatureUnion)); 969 (m_fs[plugin][n].features, 2 * sz * sizeof(VampFeatureUnion));
897 970
907 } 980 }
908 981
909 void 982 void
910 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz) 983 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz)
911 { 984 {
912 #ifdef DEBUG_PLUGIN_ADAPTER 985 // called with m_mutex held
913 std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", " 986
914 << j << ", " << sz << ")" << std::endl; 987 #ifdef DEBUG_PLUGIN_ADAPTER
988 cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
989 << j << ", " << sz << ")" << endl;
915 #endif 990 #endif
916 991
917 size_t i = m_fvsizes[plugin][n][j]; 992 size_t i = m_fvsizes[plugin][n][j];
918 if (i >= sz) return; 993 if (i >= sz) return;
919 994
920 #ifdef DEBUG_PLUGIN_ADAPTER 995 #ifdef DEBUG_PLUGIN_ADAPTER
921 std::cerr << "resizing from " << i << std::endl; 996 cerr << "resizing from " << i << endl;
922 #endif 997 #endif
923 998
924 m_fs[plugin][n].features[j].v1.values = (float *)realloc 999 m_fs[plugin][n].features[j].v1.values = (float *)realloc
925 (m_fs[plugin][n].features[j].v1.values, sz * sizeof(float)); 1000 (m_fs[plugin][n].features[j].v1.values, sz * sizeof(float));
926 1001