annotate dsp/segmentation/SavedFeatureSegmenter.cpp @ 298:255e431ae3d4

* Key detector: when returning key strengths, use the peak value of the three underlying chromagram correlations (from 36-bin chromagram) corresponding to each key, instead of the mean. Rationale: This is the same method as used when returning the key value, and it's nice to have the same results in both returned value and plot. The peak performed better than the sum with a simple test set of triads, so it seems reasonable to change the plot to match the key output rather than the other way around. * FFT: kiss_fftr returns only the non-conjugate bins, synthesise the rest rather than leaving them (perhaps dangerously) undefined. Fixes an uninitialised data error in chromagram that could cause garbage results from key detector. * Constant Q: remove precalculated values again, I reckon they're not proving such a good tradeoff.
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 05 Jun 2009 15:12:39 +0000
parents dc30e3864ceb
children
rev   line source
c@243 1 /*
c@243 2 * SavedFeatureSegmenter.cpp
c@243 3 * soundbite
c@243 4 *
c@243 5 * Created by Mark Levy on 23/03/2006.
c@243 6 * Copyright 2006 Centre for Digital Music, Queen Mary, University of London. All rights reserved.
c@243 7 *
c@243 8 */
c@243 9
c@243 10 #include <cfloat>
c@243 11 #include <cmath>
c@243 12
c@243 13 #include "SavedFeatureSegmenter.h"
c@243 14 #include "cluster_segmenter.h"
c@243 15 #include "segment.h"
c@243 16
c@243 17 SavedFeatureSegmenter::SavedFeatureSegmenter(SavedFeatureSegmenterParams params) : windowSize(params.windowSize),
c@243 18 hopSize(params.hopSize),
c@243 19 nHMMStates(params.nHMMStates),
c@243 20 nclusters(params.nclusters),
c@243 21 histogramLength(params.histogramLength),
c@243 22 neighbourhoodLimit(params.neighbourhoodLimit)
c@243 23 {
c@243 24 }
c@243 25
c@243 26 void SavedFeatureSegmenter::initialise(int fs)
c@243 27 {
c@243 28 samplerate = fs;
c@243 29 }
c@243 30
c@243 31 SavedFeatureSegmenter::~SavedFeatureSegmenter()
c@243 32 {
c@243 33 }
c@243 34
c@243 35 void SavedFeatureSegmenter::segment(int m)
c@243 36 {
c@243 37 nclusters = m;
c@243 38 segment();
c@243 39 }
c@243 40
c@243 41 void SavedFeatureSegmenter::setFeatures(const vector<vector<double> >& f)
c@243 42 {
c@243 43 features = f;
c@243 44 }
c@243 45
c@243 46 void SavedFeatureSegmenter::segment()
c@243 47 {
c@243 48 // for now copy the features to a native array and use the existing C segmenter...
c@243 49 double** arrFeatures = new double*[features.size()];
c@243 50 for (int i = 0; i < features.size(); i++)
c@243 51 {
c@243 52 arrFeatures[i] = new double[features[0].size()]; // allow space for the normalised envelope
c@243 53 for (int j = 0; j < features[0].size(); j++)
c@243 54 arrFeatures[i][j] = features[i][j];
c@243 55 }
c@243 56
c@243 57 q = new int[features.size()];
c@243 58
c@243 59 cluster_segment(q, arrFeatures, features.size(), features[0].size(), nHMMStates, histogramLength,
c@243 60 nclusters, neighbourhoodLimit);
c@243 61 // convert the cluster assignment sequence to a segmentation
c@243 62 makeSegmentation(q, features.size());
c@243 63
c@243 64 // de-allocate arrays
c@243 65 delete [] q;
c@243 66 for (int i = 0; i < features.size(); i++)
c@243 67 delete [] arrFeatures[i];
c@243 68 delete [] arrFeatures;
c@243 69
c@243 70 // clear the features
c@243 71 clear();
c@243 72 }
c@243 73
c@243 74 void SavedFeatureSegmenter::makeSegmentation(int* q, int len)
c@243 75 {
c@243 76 segmentation.segments.clear();
c@243 77 segmentation.nsegtypes = nclusters;
c@243 78 segmentation.samplerate = samplerate;
c@243 79
c@243 80 Segment segment;
c@243 81 segment.start = 0;
c@243 82 segment.type = q[0];
c@243 83
c@243 84 for (int i = 1; i < len; i++)
c@243 85 {
c@243 86 if (q[i] != q[i-1])
c@243 87 {
c@243 88 segment.end = i * getHopsize();
c@243 89 segmentation.segments.push_back(segment);
c@243 90 segment.type = q[i];
c@243 91 segment.start = segment.end;
c@243 92 }
c@243 93 }
c@243 94 segment.end = len * getHopsize();
c@243 95 segmentation.segments.push_back(segment);
c@243 96 }
c@243 97