comparison src/vamp-sdk/PluginAdapter.cpp @ 523:e0ff22b3c888 c++11-mutex

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