Mercurial > hg > vamp-plugin-sdk
comparison vamp-sdk/PluginAdapter.cpp @ 12:a3d35e11c3fe
* Avoid repeated malloc/free for returned feature lists -- reuse static
feature lists where possible. Need to document the host behaviour that
permits this (i.e. a returned feature list is only valid until the next
call to process, getRemainingFeatures or releaseFeatureSet)
author | cannam |
---|---|
date | Thu, 06 Apr 2006 15:12:25 +0000 |
parents | 44113b1e296b |
children | 85801331454c |
comparison
equal
deleted
inserted
replaced
11:6616075ec7b6 | 12:a3d35e11c3fe |
---|---|
307 } | 307 } |
308 if (desc->binNames) free((void *)desc->binNames); | 308 if (desc->binNames) free((void *)desc->binNames); |
309 free((void *)desc); | 309 free((void *)desc); |
310 } | 310 } |
311 | 311 |
312 VampFeatureList ** | 312 VampFeatureList * |
313 PluginAdapterBase::vampProcess(VampPluginHandle handle, | 313 PluginAdapterBase::vampProcess(VampPluginHandle handle, |
314 float **inputBuffers, | 314 float **inputBuffers, |
315 int sec, | 315 int sec, |
316 int nsec) | 316 int nsec) |
317 { | 317 { |
319 if (!adapter) return 0; | 319 if (!adapter) return 0; |
320 return adapter->process((Plugin *)handle, | 320 return adapter->process((Plugin *)handle, |
321 inputBuffers, sec, nsec); | 321 inputBuffers, sec, nsec); |
322 } | 322 } |
323 | 323 |
324 VampFeatureList ** | 324 VampFeatureList * |
325 PluginAdapterBase::vampGetRemainingFeatures(VampPluginHandle handle) | 325 PluginAdapterBase::vampGetRemainingFeatures(VampPluginHandle handle) |
326 { | 326 { |
327 PluginAdapterBase *adapter = lookupAdapter(handle); | 327 PluginAdapterBase *adapter = lookupAdapter(handle); |
328 if (!adapter) return 0; | 328 if (!adapter) return 0; |
329 return adapter->getRemainingFeatures((Plugin *)handle); | 329 return adapter->getRemainingFeatures((Plugin *)handle); |
330 } | 330 } |
331 | 331 |
332 void | 332 void |
333 PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList **fs) | 333 PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList *fs) |
334 { | 334 { |
335 if (!fs) return; | |
336 | |
337 for (unsigned int i = 0; fs[i]; ++i) { | |
338 | |
339 for (unsigned int j = 0; j < fs[i]->featureCount; ++j) { | |
340 VampFeature *feature = &fs[i]->features[j]; | |
341 if (feature->values) free((void *)feature->values); | |
342 if (feature->label) free((void *)feature->label); | |
343 } | |
344 | |
345 if (fs[i]->features) free((void *)fs[i]->features); | |
346 free((void *)fs[i]); | |
347 } | |
348 | |
349 free((void *)fs); | |
350 } | 335 } |
351 | 336 |
352 void | 337 void |
353 PluginAdapterBase::cleanup(Plugin *plugin) | 338 PluginAdapterBase::cleanup(Plugin *plugin) |
354 { | 339 { |
340 if (m_fs.find(plugin) != m_fs.end()) { | |
341 size_t outputCount = 0; | |
342 if (m_pluginOutputs[plugin]) { | |
343 outputCount = m_pluginOutputs[plugin]->size(); | |
344 } | |
345 VampFeatureList *list = m_fs[plugin]; | |
346 for (unsigned int i = 0; i < outputCount; ++i) { | |
347 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) { | |
348 if (list[i].features[j].label) { | |
349 free(list[i].features[j].label); | |
350 } | |
351 if (list[i].features[j].values) { | |
352 free(list[i].features[j].values); | |
353 } | |
354 } | |
355 if (list[i].features) free(list[i].features); | |
356 } | |
357 m_fs.erase(plugin); | |
358 m_fsizes.erase(plugin); | |
359 m_fvsizes.erase(plugin); | |
360 } | |
361 | |
355 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { | 362 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { |
356 delete m_pluginOutputs[plugin]; | 363 delete m_pluginOutputs[plugin]; |
357 m_pluginOutputs.erase(plugin); | 364 m_pluginOutputs.erase(plugin); |
358 } | 365 } |
359 m_adapterMap.erase(plugin); | 366 m_adapterMap.erase(plugin); |
426 desc->sampleRate = od.sampleRate; | 433 desc->sampleRate = od.sampleRate; |
427 | 434 |
428 return desc; | 435 return desc; |
429 } | 436 } |
430 | 437 |
431 VampFeatureList ** | 438 VampFeatureList * |
432 PluginAdapterBase::process(Plugin *plugin, | 439 PluginAdapterBase::process(Plugin *plugin, |
433 float **inputBuffers, | 440 float **inputBuffers, |
434 int sec, int nsec) | 441 int sec, int nsec) |
435 { | 442 { |
443 // std::cerr << "PluginAdapterBase::process" << std::endl; | |
436 RealTime rt(sec, nsec); | 444 RealTime rt(sec, nsec); |
437 return convertFeatures(plugin->process(inputBuffers, rt)); | 445 checkOutputMap(plugin); |
438 } | 446 return convertFeatures(plugin, plugin->process(inputBuffers, rt)); |
439 | 447 } |
440 VampFeatureList ** | 448 |
449 VampFeatureList * | |
441 PluginAdapterBase::getRemainingFeatures(Plugin *plugin) | 450 PluginAdapterBase::getRemainingFeatures(Plugin *plugin) |
442 { | 451 { |
443 return convertFeatures(plugin->getRemainingFeatures()); | 452 // std::cerr << "PluginAdapterBase::getRemainingFeatures" << std::endl; |
444 } | 453 checkOutputMap(plugin); |
445 | 454 return convertFeatures(plugin, plugin->getRemainingFeatures()); |
446 VampFeatureList ** | 455 } |
447 PluginAdapterBase::convertFeatures(const Plugin::FeatureSet &features) | 456 |
448 { | 457 VampFeatureList * |
449 unsigned int n = 0; | 458 PluginAdapterBase::convertFeatures(Plugin *plugin, |
450 if (features.begin() != features.end()) { | 459 const Plugin::FeatureSet &features) |
451 Plugin::FeatureSet::const_iterator i = features.end(); | 460 { |
452 --i; | 461 int lastN = -1; |
453 n = i->first + 1; | 462 |
454 } | 463 int outputCount = 0; |
455 | 464 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size(); |
456 if (!n) return 0; | 465 |
457 | 466 resizeFS(plugin, outputCount); |
458 VampFeatureList **fs = (VampFeatureList **) | 467 VampFeatureList *fs = m_fs[plugin]; |
459 malloc((n + 1) * sizeof(VampFeatureList *)); | 468 |
460 | 469 for (Plugin::FeatureSet::const_iterator fi = features.begin(); |
461 for (unsigned int i = 0; i < n; ++i) { | 470 fi != features.end(); ++fi) { |
462 | 471 |
463 fs[i] = (VampFeatureList *)malloc(sizeof(VampFeatureList)); | 472 int n = fi->first; |
464 | 473 |
465 if (features.find(i) == features.end()) { | 474 // std::cerr << "PluginAdapterBase::convertFeatures: n = " << n << std::endl; |
466 | 475 |
467 fs[i]->featureCount = 0; | 476 if (n >= int(outputCount)) { |
468 fs[i]->features = 0; | 477 std::cerr << "WARNING: PluginAdapterBase::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl; |
469 continue; | 478 continue; |
470 } | 479 } |
471 | 480 |
472 Plugin::FeatureSet::const_iterator fi = features.find(i); | 481 if (n > lastN + 1) { |
482 for (int i = lastN + 1; i < n; ++i) { | |
483 fs[i].featureCount = 0; | |
484 } | |
485 } | |
473 | 486 |
474 const Plugin::FeatureList &fl = fi->second; | 487 const Plugin::FeatureList &fl = fi->second; |
475 | 488 |
476 fs[i]->featureCount = fl.size(); | 489 size_t sz = fl.size(); |
477 | 490 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz); |
478 if (fs[i]->featureCount == 0) { | 491 fs[n].featureCount = sz; |
479 fs[i]->features = 0; | 492 |
480 continue; | 493 for (size_t j = 0; j < sz; ++j) { |
481 } | 494 |
482 | 495 // std::cerr << "PluginAdapterBase::convertFeatures: j = " << j << std::endl; |
483 fs[i]->features = (VampFeature *)malloc(fl.size() * sizeof(VampFeature)); | 496 |
484 | 497 VampFeature *feature = &fs[n].features[j]; |
485 for (unsigned int j = 0; j < fl.size(); ++j) { | |
486 | |
487 VampFeature *feature = &fs[i]->features[j]; | |
488 | 498 |
489 feature->hasTimestamp = fl[j].hasTimestamp; | 499 feature->hasTimestamp = fl[j].hasTimestamp; |
490 feature->sec = fl[j].timestamp.sec; | 500 feature->sec = fl[j].timestamp.sec; |
491 feature->nsec = fl[j].timestamp.nsec; | 501 feature->nsec = fl[j].timestamp.nsec; |
492 feature->valueCount = fl[j].values.size(); | 502 feature->valueCount = fl[j].values.size(); |
493 feature->label = strdup(fl[j].label.c_str()); | 503 |
494 | 504 if (feature->label) free(feature->label); |
495 if (feature->valueCount == 0) { | 505 |
496 feature->values = 0; | 506 if (fl[j].label.empty()) { |
497 continue; | 507 feature->label = 0; |
498 } | 508 } else { |
499 | 509 feature->label = strdup(fl[j].label.c_str()); |
500 feature->values = (float *)malloc | 510 } |
501 (feature->valueCount * sizeof(float)); | 511 |
512 if (feature->valueCount > m_fvsizes[plugin][n][j]) { | |
513 resizeFV(plugin, n, j, feature->valueCount); | |
514 } | |
502 | 515 |
503 for (unsigned int k = 0; k < feature->valueCount; ++k) { | 516 for (unsigned int k = 0; k < feature->valueCount; ++k) { |
517 // std::cerr << "PluginAdapterBase::convertFeatures: k = " << k << std::endl; | |
504 feature->values[k] = fl[j].values[k]; | 518 feature->values[k] = fl[j].values[k]; |
505 } | 519 } |
506 } | 520 } |
507 } | 521 |
508 | 522 lastN = n; |
509 fs[n] = 0; | 523 } |
524 | |
525 if (lastN == -1) return 0; | |
526 | |
527 if (int(outputCount) > lastN + 1) { | |
528 for (int i = lastN + 1; i < int(outputCount); ++i) { | |
529 fs[i].featureCount = 0; | |
530 } | |
531 } | |
510 | 532 |
511 return fs; | 533 return fs; |
512 } | 534 } |
513 | 535 |
536 void | |
537 PluginAdapterBase::resizeFS(Plugin *plugin, int n) | |
538 { | |
539 // std::cerr << "PluginAdapterBase::resizeFS(" << plugin << ", " << n << ")" << std::endl; | |
540 | |
541 int i = m_fsizes[plugin].size(); | |
542 if (i >= n) return; | |
543 | |
544 std::cerr << "resizing from " << i << std::endl; | |
545 | |
546 m_fs[plugin] = (VampFeatureList *)realloc | |
547 (m_fs[plugin], n * sizeof(VampFeatureList)); | |
548 | |
549 while (i < n) { | |
550 m_fs[plugin][i].featureCount = 0; | |
551 m_fs[plugin][i].features = 0; | |
552 m_fsizes[plugin].push_back(0); | |
553 m_fvsizes[plugin].push_back(std::vector<size_t>()); | |
554 i++; | |
555 } | |
556 } | |
557 | |
558 void | |
559 PluginAdapterBase::resizeFL(Plugin *plugin, int n, size_t sz) | |
560 { | |
561 std::cerr << "PluginAdapterBase::resizeFL(" << plugin << ", " << n << ", " | |
562 << sz << ")" << std::endl; | |
563 | |
564 size_t i = m_fsizes[plugin][n]; | |
565 if (i >= sz) return; | |
566 | |
567 std::cerr << "resizing from " << i << std::endl; | |
568 | |
569 m_fs[plugin][n].features = (VampFeature *)realloc | |
570 (m_fs[plugin][n].features, sz * sizeof(VampFeature)); | |
571 | |
572 while (m_fsizes[plugin][n] < sz) { | |
573 m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0; | |
574 m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0; | |
575 m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0; | |
576 m_fvsizes[plugin][n].push_back(0); | |
577 m_fsizes[plugin][n]++; | |
578 } | |
579 } | |
580 | |
581 void | |
582 PluginAdapterBase::resizeFV(Plugin *plugin, int n, int j, size_t sz) | |
583 { | |
584 | |
585 std::cerr << "PluginAdapterBase::resizeFV(" << plugin << ", " << n << ", " | |
586 << j << ", " << sz << ")" << std::endl; | |
587 | |
588 size_t i = m_fvsizes[plugin][n][j]; | |
589 if (i >= sz) return; | |
590 | |
591 std::cerr << "resizing from " << i << std::endl; | |
592 | |
593 m_fs[plugin][n].features[j].values = (float *)realloc | |
594 (m_fs[plugin][n].features[j].values, sz * sizeof(float)); | |
595 | |
596 m_fvsizes[plugin][n][j] = sz; | |
597 } | |
598 | |
514 PluginAdapterBase::AdapterMap | 599 PluginAdapterBase::AdapterMap |
515 PluginAdapterBase::m_adapterMap; | 600 PluginAdapterBase::m_adapterMap; |
516 | 601 |
517 } | 602 } |
518 | 603 |