comparison plugins/SimilarityPlugin.cpp @ 44:1dc00e4dbae6

* add a sorted vector output
author Chris Cannam <c.cannam@qmul.ac.uk>
date Thu, 17 Jan 2008 15:37:37 +0000
parents 1389f05cb688
children 5d7ce1d87301
comparison
equal deleted inserted replaced
43:1389f05cb688 44:1dc00e4dbae6
6 * Copyright 2008 Centre for Digital Music, Queen Mary, University of London. 6 * Copyright 2008 Centre for Digital Music, Queen Mary, University of London.
7 * All rights reserved. 7 * All rights reserved.
8 */ 8 */
9 9
10 #include <iostream> 10 #include <iostream>
11 #include <sstream> 11 #include <cstdio>
12 12
13 #include "SimilarityPlugin.h" 13 #include "SimilarityPlugin.h"
14 #include "base/Pitch.h" 14 #include "base/Pitch.h"
15 #include "dsp/mfcc/MFCC.h" 15 #include "dsp/mfcc/MFCC.h"
16 #include "dsp/chromagram/Chromagram.h" 16 #include "dsp/chromagram/Chromagram.h"
86 86
87 size_t 87 size_t
88 SimilarityPlugin::getMaxChannelCount() const 88 SimilarityPlugin::getMaxChannelCount() const
89 { 89 {
90 return 1024; 90 return 1024;
91 // return 1;
91 } 92 }
92 93
93 bool 94 bool
94 SimilarityPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize) 95 SimilarityPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize)
95 { 96 {
112 return false; 113 return false;
113 } 114 }
114 115
115 m_blockSize = blockSize; 116 m_blockSize = blockSize;
116 m_channels = channels; 117 m_channels = channels;
118
119 m_lastNonEmptyFrame = std::vector<int>(m_channels);
120 for (int i = 0; i < m_channels; ++i) m_lastNonEmptyFrame[i] = -1;
121 m_frameNo = 0;
117 122
118 int decimationFactor = getDecimationFactor(); 123 int decimationFactor = getDecimationFactor();
119 if (decimationFactor > 1) { 124 if (decimationFactor > 1) {
120 m_decimator = new Decimator(m_blockSize, decimationFactor); 125 m_decimator = new Decimator(m_blockSize, decimationFactor);
121 } 126 }
309 simvec.sampleRate = 1; 314 simvec.sampleRate = 1;
310 315
311 m_distanceVectorOutput = list.size(); 316 m_distanceVectorOutput = list.size();
312 list.push_back(simvec); 317 list.push_back(simvec);
313 318
319 OutputDescriptor sortvec;
320 sortvec.identifier = "sorteddistancevector";
321 sortvec.name = "Ordered Distances from First Channel";
322 sortvec.description = "Vector of the order of other channels in similarity to the first, followed by distance vector for similarity of each to the first. Smaller = more similar.";
323 sortvec.unit = "";
324 sortvec.hasFixedBinCount = true;
325 sortvec.binCount = m_channels;
326 sortvec.hasKnownExtents = false;
327 sortvec.isQuantized = false;
328 sortvec.sampleType = OutputDescriptor::FixedSampleRate;
329 sortvec.sampleRate = 1;
330
331 m_sortedVectorOutput = list.size();
332 list.push_back(sortvec);
333
314 OutputDescriptor means; 334 OutputDescriptor means;
315 means.identifier = "means"; 335 means.identifier = "means";
316 means.name = "Feature Means"; 336 means.name = "Feature Means";
317 means.description = "Means of the feature bins. Feature time (sec) corresponds to input channel. Number of bins depends on selected feature type."; 337 means.description = "Means of the feature bins. Feature time (sec) corresponds to input channel. Number of bins depends on selected feature type.";
318 means.unit = ""; 338 means.unit = "";
370 if (fabs(val) > threshold) empty = false; 390 if (fabs(val) > threshold) empty = false;
371 dblbuf[i] = val; 391 dblbuf[i] = val;
372 } 392 }
373 393
374 if (empty) continue; 394 if (empty) continue;
395 m_lastNonEmptyFrame[c] = m_frameNo;
375 396
376 if (m_decimator) { 397 if (m_decimator) {
377 m_decimator->process(dblbuf, decbuf); 398 m_decimator->process(dblbuf, decbuf);
378 } 399 }
379 400
382 } else if (m_type == TypeChroma) { 403 } else if (m_type == TypeChroma) {
383 raw = m_chromagram->process(decbuf); 404 raw = m_chromagram->process(decbuf);
384 } 405 }
385 406
386 FeatureColumn mf(m_featureColumnSize); 407 FeatureColumn mf(m_featureColumnSize);
387 for (int i = 0; i < m_featureColumnSize; ++i) mf[i] = raw[i]; 408 // std::cout << m_frameNo << ":" << c << ": ";
409 for (int i = 0; i < m_featureColumnSize; ++i) {
410 mf[i] = raw[i];
411 // std::cout << raw[i] << " ";
412 }
413 // std::cout << std::endl;
388 414
389 m_values[c].push_back(mf); 415 m_values[c].push_back(mf);
390 } 416 }
391 417
392 if (m_decimator) delete[] decbuf; 418 if (m_decimator) delete[] decbuf;
393 delete[] dblbuf; 419 delete[] dblbuf;
394 420
395 if (ownRaw) delete[] raw; 421 if (ownRaw) delete[] raw;
396 422
423 ++m_frameNo;
424
397 return FeatureSet(); 425 return FeatureSet();
398 } 426 }
399 427
400 SimilarityPlugin::FeatureSet 428 SimilarityPlugin::FeatureSet
401 SimilarityPlugin::getRemainingFeatures() 429 SimilarityPlugin::getRemainingFeatures()
411 439
412 mean[j] = 0.0; 440 mean[j] = 0.0;
413 variance[j] = 0.0; 441 variance[j] = 0.0;
414 int count; 442 int count;
415 443
416 // we need to use at least one value, but we want to 444 // We want to take values up to, but not including, the
417 // disregard the final value because it may have come from 445 // last non-empty frame (which may be partial)
418 // incomplete data 446
419 447 int sz = m_lastNonEmptyFrame[i];
420 int sz = m_values[i].size(); 448 if (sz < 0) sz = 0;
421 if (sz > 1) --sz;
422 449
423 // std::cout << "\nBin " << j << ":" << std::endl; 450 // std::cout << "\nBin " << j << ":" << std::endl;
424 451
425 count = 0; 452 count = 0;
426 for (int k = 0; k < sz; ++k) { 453 for (int k = 0; k < sz; ++k) {
482 d /= 2.0; 509 d /= 2.0;
483 distances[i].push_back(d); 510 distances[i].push_back(d);
484 } 511 }
485 } 512 }
486 513
514 // We give all features a timestamp, otherwise hosts will tend to
515 // stamp them at the end of the file, which is annoying
516
487 FeatureSet returnFeatures; 517 FeatureSet returnFeatures;
518
519 Feature feature;
520 feature.hasTimestamp = true;
488 521
489 Feature distanceVectorFeature; 522 Feature distanceVectorFeature;
490 distanceVectorFeature.label = "Distance from first channel"; 523 distanceVectorFeature.label = "Distance from first channel";
524 distanceVectorFeature.hasTimestamp = true;
525 distanceVectorFeature.timestamp = Vamp::RealTime::zeroTime;
526
527 std::map<double, int> sorted;
528
529 char labelBuffer[100];
491 530
492 for (int i = 0; i < m_channels; ++i) { 531 for (int i = 0; i < m_channels; ++i) {
493 532
494 Feature feature;
495 feature.hasTimestamp = true; // otherwise hosts will tend to stamp them at the end of the file, which is annoying
496 feature.timestamp = Vamp::RealTime(i, 0); 533 feature.timestamp = Vamp::RealTime(i, 0);
534
535 sprintf(labelBuffer, "Means for channel %d", i+1);
536 feature.label = labelBuffer;
497 537
498 feature.values.clear(); 538 feature.values.clear();
499 for (int k = 0; k < m_featureColumnSize; ++k) { 539 for (int k = 0; k < m_featureColumnSize; ++k) {
500 feature.values.push_back(m[i][k]); 540 feature.values.push_back(m[i][k]);
501 } 541 }
502 542
503 returnFeatures[m_meansOutput].push_back(feature); 543 returnFeatures[m_meansOutput].push_back(feature);
504 544
545 sprintf(labelBuffer, "Variances for channel %d", i+1);
546 feature.label = labelBuffer;
547
505 feature.values.clear(); 548 feature.values.clear();
506 for (int k = 0; k < m_featureColumnSize; ++k) { 549 for (int k = 0; k < m_featureColumnSize; ++k) {
507 feature.values.push_back(v[i][k]); 550 feature.values.push_back(v[i][k]);
508 } 551 }
509 552
512 feature.values.clear(); 555 feature.values.clear();
513 for (int j = 0; j < m_channels; ++j) { 556 for (int j = 0; j < m_channels; ++j) {
514 feature.values.push_back(distances[i][j]); 557 feature.values.push_back(distances[i][j]);
515 } 558 }
516 559
517 ostringstream oss; 560 sprintf(labelBuffer, "Distances from channel %d", i+1);
518 oss << "Distance from " << (i + 1); 561 feature.label = labelBuffer;
519 feature.label = oss.str();
520 562
521 returnFeatures[m_distanceMatrixOutput].push_back(feature); 563 returnFeatures[m_distanceMatrixOutput].push_back(feature);
522 564
523 distanceVectorFeature.values.push_back(distances[0][i]); 565 distanceVectorFeature.values.push_back(distances[0][i]);
566
567 sorted[distances[0][i]] = i;
524 } 568 }
525 569
526 returnFeatures[m_distanceVectorOutput].push_back(distanceVectorFeature); 570 returnFeatures[m_distanceVectorOutput].push_back(distanceVectorFeature);
527 571
572 feature.label = "Order of channels by similarity to first channel";
573 feature.values.clear();
574 feature.timestamp = Vamp::RealTime(0, 0);
575
576 for (std::map<double, int>::iterator i = sorted.begin();
577 i != sorted.end(); ++i) {
578 feature.values.push_back(i->second);
579 }
580
581 returnFeatures[m_sortedVectorOutput].push_back(feature);
582
583 feature.label = "Ordered distances of channels from first channel";
584 feature.values.clear();
585 feature.timestamp = Vamp::RealTime(1, 0);
586
587 for (std::map<double, int>::iterator i = sorted.begin();
588 i != sorted.end(); ++i) {
589 feature.values.push_back(i->first);
590 }
591
592 returnFeatures[m_sortedVectorOutput].push_back(feature);
593
528 return returnFeatures; 594 return returnFeatures;
529 } 595 }