Mercurial > hg > qm-vamp-plugins
diff plugins/SegmenterPlugin.cpp @ 36:5359ba489c0f
* Add segmenter plugin code (not built yet)
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 09 Jan 2008 10:39:43 +0000 |
parents | |
children | 9ce0db4770a2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/SegmenterPlugin.cpp Wed Jan 09 10:39:43 2008 +0000 @@ -0,0 +1,251 @@ +/* + * SegmenterPlugin.cpp + * soundbite + * + * Created by Mark Levy on 24/03/2006. + * Copyright 2006 Centre for Digital Music, Queen Mary, University of London. All rights reserved. + * + */ + +#include <iostream> +#include <sstream> + +#include "SegmenterPlugin.h" +#include "ClusterMeltSegmenter.h" + +using std::string; +using std::vector; +using std::cerr; +using std::endl; +using std::ostringstream; + +SegmenterPlugin::SegmenterPlugin(float inputSampleRate) : + Plugin(inputSampleRate), segmenter(0), nSegmentTypes(10), featureType(feature_types(1)) +{ + +} + +SegmenterPlugin::~SegmenterPlugin() +{ + if (segmenter) + delete segmenter; +} + +string +SegmenterPlugin::getMaker() const +{ + return "Mark Levy, Queen Mary, University of London"; +} + +int +SegmenterPlugin::getPluginVersion() const +{ + return 2; +} + +string +SegmenterPlugin::getCopyright() const +{ + return "All rights reserved"; +} + +bool +SegmenterPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize) +{ + if (channels < getMinChannelCount() || + channels > getMaxChannelCount()) return false; + + if (!segmenter) makeSegmenter(); + + //!!! TODO: print out a helpful error message + + if (stepSize != hopsize) return false; + if (blockSize != windowsize) return false; + + return true; +} + +void +SegmenterPlugin::reset() +{ +} + +size_t +SegmenterPlugin::getPreferredStepSize() const +{ + if (!segmenter) makeSegmenter(); + return hopsize; +} + +size_t +SegmenterPlugin::getPreferredBlockSize() const +{ + if (!segmenter) makeSegmenter(); + return windowsize; +} + +SegmenterPlugin::ParameterList SegmenterPlugin::getParameterDescriptors() const +{ + ParameterList list; + + ParameterDescriptor desc; + desc.identifier = "nSegmentTypes"; + desc.name = "Number of segment-types"; + desc.description = "Maximum number of different kinds of segment to find"; + desc.unit = ""; + desc.minValue = 2; + desc.maxValue = 12; + desc.defaultValue = 10; + desc.isQuantized = true; + desc.quantizeStep = 1; + list.push_back(desc); + + ParameterDescriptor desc2; + desc2.identifier = "featureType"; + desc2.name = "Feature Type"; + desc2.description = "Try Chroma for acoustic or pre-1980 recordings, otherwise use Constant-Q"; + desc2.unit = ""; + desc2.minValue = 1; + desc2.maxValue = 2; + desc2.defaultValue = 1; + desc2.isQuantized = true; + desc2.quantizeStep = 1; + desc2.valueNames.push_back("Constant-Q"); + desc2.valueNames.push_back("Chroma"); + list.push_back(desc2); + + return list; +} + +float +SegmenterPlugin::getParameter(std::string param) const +{ + if (param == "nSegmentTypes") { + return nSegmentTypes; + } + + if (param == "featureType") { + return featureType; + } + + std::cerr << "WARNING: SegmenterPlugin::getParameter: unknown parameter \"" + << param << "\"" << std::endl; + return 0.0; +} + +void +SegmenterPlugin::setParameter(std::string param, float value) +{ + if (param == "nSegmentTypes") { + nSegmentTypes = int(value); + } else + { + if (param == "featureType") { + if (featureType != feature_types(value)) // feature type changed, create a new segmenter + { + featureType = feature_types(value); + makeSegmenter(); + } + } + else + { + std::cerr << "WARNING: SegmenterPlugin::setParameter: unknown parameter \"" + << param << "\"" << std::endl; + } + } +} + +void +SegmenterPlugin::makeSegmenter() const +{ + ClusterMeltSegmenterParams params = ClusterMeltSegmenterParams(); + params.featureType = (feature_types) featureType; + if (params.featureType == FEATURE_TYPE_CONSTQ) + { + params.ncomponents = 20; + params.neighbourhoodLimit = 30; + } + if (params.featureType == FEATURE_TYPE_CHROMA) + { + params.hopSize = 0.1; + params.windowSize = 0.372; + params.nbins = 12; + params.histogramLength = 20; + params.neighbourhoodLimit = 40; + } + delete segmenter; + segmenter = new ClusterMeltSegmenter(params); + segmenter->initialise(static_cast<int>(m_inputSampleRate)); + hopsize = segmenter->getHopsize(); + windowsize = segmenter->getWindowsize(); +} + +SegmenterPlugin::OutputList +SegmenterPlugin::getOutputDescriptors() const +{ + OutputList list; + + OutputDescriptor segmentation; + segmentation.identifier = "segmentation"; + segmentation.name = "Segmentation"; + segmentation.description = "Segmentation"; + segmentation.unit = "segment-type"; + segmentation.hasFixedBinCount = true; + segmentation.binCount = 1; + segmentation.minValue = 1; + segmentation.maxValue = nSegmentTypes; + segmentation.isQuantized = true; + segmentation.quantizeStep = 1; + segmentation.sampleType = OutputDescriptor::VariableSampleRate; + segmentation.sampleRate = m_inputSampleRate / getPreferredStepSize(); + + list.push_back(segmentation); + + return list; +} + +SegmenterPlugin::FeatureSet +SegmenterPlugin::process(const float *const *inputBuffers, Vamp::RealTime /* timestamp */) +{ + // convert float* to double* + double *tempBuffer = new double[windowsize]; + for (size_t i = 0; i < windowsize; ++i) { + tempBuffer[i] = inputBuffers[0][i]; + } + + segmenter->extractFeatures(tempBuffer, windowsize); + + delete [] tempBuffer; + + return FeatureSet(); +} + +SegmenterPlugin::FeatureSet +SegmenterPlugin::getRemainingFeatures() +{ + segmenter->segment(nSegmentTypes); + Segmentation segm = segmenter->getSegmentation(); + + FeatureSet returnFeatures; + + for (int i = 0; i < segm.segments.size(); ++i) { + + Segment s = segm.segments[i]; + + Feature feature; + feature.hasTimestamp = true; + feature.timestamp = Vamp::RealTime::frame2RealTime(s.start, static_cast<unsigned int>(m_inputSampleRate)); + + vector<float> floatval; + floatval.push_back(s.type); + feature.values = floatval; + + ostringstream oss; + oss << s.type; + feature.label = oss.str(); + + returnFeatures[0].push_back(feature); + } + + return returnFeatures; +}