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