annotate plugins/SegmenterPlugin.cpp @ 37:9ce0db4770a2

* work on integrating segmenter (not yet done)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Wed, 09 Jan 2008 16:51:59 +0000
parents 5359ba489c0f
children 9a2edd83775f
rev   line source
c@36 1 /*
c@36 2 * SegmenterPlugin.cpp
c@36 3 * soundbite
c@36 4 *
c@36 5 * Created by Mark Levy on 24/03/2006.
c@36 6 * Copyright 2006 Centre for Digital Music, Queen Mary, University of London. All rights reserved.
c@36 7 *
c@36 8 */
c@36 9
c@36 10 #include <iostream>
c@36 11 #include <sstream>
c@36 12
c@36 13 #include "SegmenterPlugin.h"
c@37 14 #include "dsp/segmentation/ClusterMeltSegmenter.h"
c@36 15
c@36 16 using std::string;
c@36 17 using std::vector;
c@36 18 using std::cerr;
c@36 19 using std::endl;
c@36 20 using std::ostringstream;
c@36 21
c@36 22 SegmenterPlugin::SegmenterPlugin(float inputSampleRate) :
c@36 23 Plugin(inputSampleRate), segmenter(0), nSegmentTypes(10), featureType(feature_types(1))
c@36 24 {
c@36 25
c@36 26 }
c@36 27
c@36 28 SegmenterPlugin::~SegmenterPlugin()
c@36 29 {
c@36 30 if (segmenter)
c@36 31 delete segmenter;
c@36 32 }
c@36 33
c@36 34 string
c@36 35 SegmenterPlugin::getMaker() const
c@36 36 {
c@36 37 return "Mark Levy, Queen Mary, University of London";
c@36 38 }
c@36 39
c@36 40 int
c@36 41 SegmenterPlugin::getPluginVersion() const
c@36 42 {
c@36 43 return 2;
c@36 44 }
c@36 45
c@36 46 string
c@36 47 SegmenterPlugin::getCopyright() const
c@36 48 {
c@37 49 return "Copyright (c) 2006-2008 - All Rights Reserved";
c@36 50 }
c@36 51
c@36 52 bool
c@36 53 SegmenterPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize)
c@36 54 {
c@36 55 if (channels < getMinChannelCount() ||
c@36 56 channels > getMaxChannelCount()) return false;
c@36 57
c@36 58 if (!segmenter) makeSegmenter();
c@36 59
c@36 60 //!!! TODO: print out a helpful error message
c@36 61
c@36 62 if (stepSize != hopsize) return false;
c@36 63 if (blockSize != windowsize) return false;
c@36 64
c@36 65 return true;
c@36 66 }
c@36 67
c@36 68 void
c@36 69 SegmenterPlugin::reset()
c@36 70 {
c@36 71 }
c@36 72
c@36 73 size_t
c@36 74 SegmenterPlugin::getPreferredStepSize() const
c@36 75 {
c@36 76 if (!segmenter) makeSegmenter();
c@36 77 return hopsize;
c@36 78 }
c@36 79
c@36 80 size_t
c@36 81 SegmenterPlugin::getPreferredBlockSize() const
c@36 82 {
c@36 83 if (!segmenter) makeSegmenter();
c@36 84 return windowsize;
c@36 85 }
c@36 86
c@36 87 SegmenterPlugin::ParameterList SegmenterPlugin::getParameterDescriptors() const
c@36 88 {
c@36 89 ParameterList list;
c@36 90
c@36 91 ParameterDescriptor desc;
c@36 92 desc.identifier = "nSegmentTypes";
c@36 93 desc.name = "Number of segment-types";
c@36 94 desc.description = "Maximum number of different kinds of segment to find";
c@36 95 desc.unit = "";
c@36 96 desc.minValue = 2;
c@36 97 desc.maxValue = 12;
c@36 98 desc.defaultValue = 10;
c@36 99 desc.isQuantized = true;
c@36 100 desc.quantizeStep = 1;
c@36 101 list.push_back(desc);
c@36 102
c@36 103 ParameterDescriptor desc2;
c@36 104 desc2.identifier = "featureType";
c@36 105 desc2.name = "Feature Type";
c@36 106 desc2.description = "Try Chroma for acoustic or pre-1980 recordings, otherwise use Constant-Q";
c@36 107 desc2.unit = "";
c@36 108 desc2.minValue = 1;
c@36 109 desc2.maxValue = 2;
c@36 110 desc2.defaultValue = 1;
c@36 111 desc2.isQuantized = true;
c@36 112 desc2.quantizeStep = 1;
c@36 113 desc2.valueNames.push_back("Constant-Q");
c@36 114 desc2.valueNames.push_back("Chroma");
c@36 115 list.push_back(desc2);
c@36 116
c@36 117 return list;
c@36 118 }
c@36 119
c@36 120 float
c@36 121 SegmenterPlugin::getParameter(std::string param) const
c@36 122 {
c@36 123 if (param == "nSegmentTypes") {
c@36 124 return nSegmentTypes;
c@36 125 }
c@36 126
c@36 127 if (param == "featureType") {
c@36 128 return featureType;
c@36 129 }
c@36 130
c@36 131 std::cerr << "WARNING: SegmenterPlugin::getParameter: unknown parameter \""
c@36 132 << param << "\"" << std::endl;
c@36 133 return 0.0;
c@36 134 }
c@36 135
c@36 136 void
c@36 137 SegmenterPlugin::setParameter(std::string param, float value)
c@36 138 {
c@36 139 if (param == "nSegmentTypes") {
c@36 140 nSegmentTypes = int(value);
c@36 141 } else
c@36 142 {
c@36 143 if (param == "featureType") {
c@36 144 if (featureType != feature_types(value)) // feature type changed, create a new segmenter
c@36 145 {
c@36 146 featureType = feature_types(value);
c@36 147 makeSegmenter();
c@36 148 }
c@36 149 }
c@36 150 else
c@36 151 {
c@36 152 std::cerr << "WARNING: SegmenterPlugin::setParameter: unknown parameter \""
c@36 153 << param << "\"" << std::endl;
c@36 154 }
c@36 155 }
c@36 156 }
c@36 157
c@36 158 void
c@36 159 SegmenterPlugin::makeSegmenter() const
c@36 160 {
c@36 161 ClusterMeltSegmenterParams params = ClusterMeltSegmenterParams();
c@36 162 params.featureType = (feature_types) featureType;
c@36 163 if (params.featureType == FEATURE_TYPE_CONSTQ)
c@36 164 {
c@36 165 params.ncomponents = 20;
c@37 166 params.neighbourhoodLimit = 30;
c@36 167 }
c@36 168 if (params.featureType == FEATURE_TYPE_CHROMA)
c@36 169 {
c@36 170 params.hopSize = 0.1;
c@36 171 params.windowSize = 0.372;
c@36 172 params.nbins = 12;
c@36 173 params.histogramLength = 20;
c@36 174 params.neighbourhoodLimit = 40;
c@36 175 }
c@36 176 delete segmenter;
c@36 177 segmenter = new ClusterMeltSegmenter(params);
c@36 178 segmenter->initialise(static_cast<int>(m_inputSampleRate));
c@36 179 hopsize = segmenter->getHopsize();
c@36 180 windowsize = segmenter->getWindowsize();
c@36 181 }
c@36 182
c@36 183 SegmenterPlugin::OutputList
c@36 184 SegmenterPlugin::getOutputDescriptors() const
c@36 185 {
c@36 186 OutputList list;
c@36 187
c@36 188 OutputDescriptor segmentation;
c@36 189 segmentation.identifier = "segmentation";
c@36 190 segmentation.name = "Segmentation";
c@36 191 segmentation.description = "Segmentation";
c@36 192 segmentation.unit = "segment-type";
c@36 193 segmentation.hasFixedBinCount = true;
c@36 194 segmentation.binCount = 1;
c@36 195 segmentation.minValue = 1;
c@36 196 segmentation.maxValue = nSegmentTypes;
c@36 197 segmentation.isQuantized = true;
c@36 198 segmentation.quantizeStep = 1;
c@36 199 segmentation.sampleType = OutputDescriptor::VariableSampleRate;
c@36 200 segmentation.sampleRate = m_inputSampleRate / getPreferredStepSize();
c@36 201
c@36 202 list.push_back(segmentation);
c@36 203
c@36 204 return list;
c@36 205 }
c@36 206
c@36 207 SegmenterPlugin::FeatureSet
c@36 208 SegmenterPlugin::process(const float *const *inputBuffers, Vamp::RealTime /* timestamp */)
c@36 209 {
c@36 210 // convert float* to double*
c@36 211 double *tempBuffer = new double[windowsize];
c@36 212 for (size_t i = 0; i < windowsize; ++i) {
c@36 213 tempBuffer[i] = inputBuffers[0][i];
c@36 214 }
c@36 215
c@36 216 segmenter->extractFeatures(tempBuffer, windowsize);
c@36 217
c@36 218 delete [] tempBuffer;
c@36 219
c@36 220 return FeatureSet();
c@36 221 }
c@36 222
c@36 223 SegmenterPlugin::FeatureSet
c@36 224 SegmenterPlugin::getRemainingFeatures()
c@36 225 {
c@36 226 segmenter->segment(nSegmentTypes);
c@36 227 Segmentation segm = segmenter->getSegmentation();
c@36 228
c@36 229 FeatureSet returnFeatures;
c@36 230
c@36 231 for (int i = 0; i < segm.segments.size(); ++i) {
c@36 232
c@36 233 Segment s = segm.segments[i];
c@36 234
c@36 235 Feature feature;
c@36 236 feature.hasTimestamp = true;
c@36 237 feature.timestamp = Vamp::RealTime::frame2RealTime(s.start, static_cast<unsigned int>(m_inputSampleRate));
c@36 238
c@36 239 vector<float> floatval;
c@36 240 floatval.push_back(s.type);
c@36 241 feature.values = floatval;
c@36 242
c@36 243 ostringstream oss;
c@36 244 oss << s.type;
c@36 245 feature.label = oss.str();
c@36 246
c@36 247 returnFeatures[0].push_back(feature);
c@36 248 }
c@36 249
c@36 250 return returnFeatures;
c@36 251 }