annotate examples/SpectralCentroid.cpp @ 263:4454843ff384

* OK, we're going to have to place the host stuff in its own namespace too. Otherwise our new SV build on OSX fails to load old plugins because they pull in the host namespace PluginBase and thus report the wrong Vamp version... *sigh*
author cannam
date Thu, 20 Nov 2008 15:01:30 +0000
parents 88ef5ffdbe8d
children 91574fc544db
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 Vamp
cannam@0 5
cannam@0 6 An API for audio analysis and feature extraction plugins.
cannam@0 7
cannam@0 8 Centre for Digital Music, Queen Mary, University of London.
cannam@0 9 Copyright 2006 Chris Cannam.
cannam@0 10
cannam@0 11 Permission is hereby granted, free of charge, to any person
cannam@0 12 obtaining a copy of this software and associated documentation
cannam@0 13 files (the "Software"), to deal in the Software without
cannam@0 14 restriction, including without limitation the rights to use, copy,
cannam@0 15 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@0 16 of the Software, and to permit persons to whom the Software is
cannam@0 17 furnished to do so, subject to the following conditions:
cannam@0 18
cannam@0 19 The above copyright notice and this permission notice shall be
cannam@0 20 included in all copies or substantial portions of the Software.
cannam@0 21
cannam@0 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@0 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@0 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@6 25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@0 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@0 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@0 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@0 29
cannam@0 30 Except as contained in this notice, the names of the Centre for
cannam@0 31 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@0 32 shall not be used in advertising or otherwise to promote the sale,
cannam@0 33 use or other dealings in this Software without prior written
cannam@0 34 authorization.
cannam@0 35 */
cannam@0 36
cannam@0 37 #include "SpectralCentroid.h"
cannam@0 38
cannam@0 39 using std::string;
cannam@0 40 using std::vector;
cannam@0 41 using std::cerr;
cannam@0 42 using std::endl;
cannam@0 43
cannam@210 44 #include <math.h>
cannam@7 45
cannam@210 46 #ifdef WIN32
cannam@210 47 #define isnan(x) false
cannam@210 48 #define isinf(x) false
cannam@210 49 #endif
cannam@0 50
cannam@0 51 SpectralCentroid::SpectralCentroid(float inputSampleRate) :
cannam@0 52 Plugin(inputSampleRate),
cannam@0 53 m_stepSize(0),
cannam@21 54 m_blockSize(0)
cannam@0 55 {
cannam@0 56 }
cannam@0 57
cannam@0 58 SpectralCentroid::~SpectralCentroid()
cannam@0 59 {
cannam@0 60 }
cannam@0 61
cannam@0 62 string
cannam@49 63 SpectralCentroid::getIdentifier() const
cannam@0 64 {
cannam@0 65 return "spectralcentroid";
cannam@0 66 }
cannam@0 67
cannam@0 68 string
cannam@49 69 SpectralCentroid::getName() const
cannam@49 70 {
cannam@49 71 return "Spectral Centroid";
cannam@49 72 }
cannam@49 73
cannam@49 74 string
cannam@0 75 SpectralCentroid::getDescription() const
cannam@0 76 {
cannam@49 77 return "Calculate the centroid frequency of the spectrum of the input signal";
cannam@0 78 }
cannam@0 79
cannam@0 80 string
cannam@0 81 SpectralCentroid::getMaker() const
cannam@0 82 {
cannam@43 83 return "Vamp SDK Example Plugins";
cannam@0 84 }
cannam@0 85
cannam@0 86 int
cannam@0 87 SpectralCentroid::getPluginVersion() const
cannam@0 88 {
cannam@0 89 return 2;
cannam@0 90 }
cannam@0 91
cannam@0 92 string
cannam@0 93 SpectralCentroid::getCopyright() const
cannam@0 94 {
cannam@7 95 return "Freely redistributable (BSD license)";
cannam@0 96 }
cannam@0 97
cannam@0 98 bool
cannam@0 99 SpectralCentroid::initialise(size_t channels, size_t stepSize, size_t blockSize)
cannam@0 100 {
cannam@0 101 if (channels < getMinChannelCount() ||
cannam@0 102 channels > getMaxChannelCount()) return false;
cannam@0 103
cannam@0 104 m_stepSize = stepSize;
cannam@0 105 m_blockSize = blockSize;
cannam@0 106
cannam@0 107 return true;
cannam@0 108 }
cannam@0 109
cannam@0 110 void
cannam@0 111 SpectralCentroid::reset()
cannam@0 112 {
cannam@0 113 }
cannam@0 114
cannam@0 115 SpectralCentroid::OutputList
cannam@0 116 SpectralCentroid::getOutputDescriptors() const
cannam@0 117 {
cannam@0 118 OutputList list;
cannam@0 119
cannam@0 120 OutputDescriptor d;
cannam@49 121 d.identifier = "logcentroid";
cannam@49 122 d.name = "Log Frequency Centroid";
cannam@49 123 d.description = "Centroid of the log weighted frequency spectrum";
cannam@0 124 d.unit = "Hz";
cannam@9 125 d.hasFixedBinCount = true;
cannam@9 126 d.binCount = 1;
cannam@0 127 d.hasKnownExtents = false;
cannam@0 128 d.isQuantized = false;
cannam@0 129 d.sampleType = OutputDescriptor::OneSamplePerStep;
cannam@0 130 list.push_back(d);
cannam@0 131
cannam@49 132 d.identifier = "linearcentroid";
cannam@49 133 d.name = "Linear Frequency Centroid";
cannam@49 134 d.description = "Centroid of the linear frequency spectrum";
cannam@0 135 list.push_back(d);
cannam@0 136
cannam@0 137 return list;
cannam@0 138 }
cannam@0 139
cannam@0 140 SpectralCentroid::FeatureSet
cannam@190 141 SpectralCentroid::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
cannam@0 142 {
cannam@0 143 if (m_stepSize == 0) {
cannam@0 144 cerr << "ERROR: SpectralCentroid::process: "
cannam@0 145 << "SpectralCentroid has not been initialised"
cannam@0 146 << endl;
cannam@0 147 return FeatureSet();
cannam@0 148 }
cannam@0 149
cannam@0 150 double numLin = 0.0, numLog = 0.0, denom = 0.0;
cannam@0 151
cannam@47 152 for (size_t i = 1; i <= m_blockSize/2; ++i) {
cannam@0 153 double freq = (double(i) * m_inputSampleRate) / m_blockSize;
cannam@0 154 double real = inputBuffers[0][i*2];
cannam@0 155 double imag = inputBuffers[0][i*2 + 1];
cannam@243 156 double scalemag = sqrt(real * real + imag * imag) / (m_blockSize/2);
cannam@243 157 numLin += freq * scalemag;
cannam@243 158 numLog += log10f(freq) * scalemag;
cannam@243 159 denom += scalemag;
cannam@0 160 }
cannam@0 161
cannam@0 162 FeatureSet returnFeatures;
cannam@0 163
cannam@0 164 if (denom != 0.0) {
cannam@0 165 float centroidLin = float(numLin / denom);
cannam@19 166 float centroidLog = powf(10, float(numLog / denom));
cannam@47 167
cannam@0 168 Feature feature;
cannam@0 169 feature.hasTimestamp = false;
cannam@243 170
cannam@243 171 if (!isnan(centroidLog) && !isinf(centroidLog)) {
cannam@243 172 feature.values.push_back(centroidLog);
cannam@243 173 }
cannam@0 174 returnFeatures[0].push_back(feature);
cannam@47 175
cannam@243 176 feature.values.clear();
cannam@243 177 if (!isnan(centroidLin) && !isinf(centroidLin)) {
cannam@243 178 feature.values.push_back(centroidLin);
cannam@243 179 }
cannam@0 180 returnFeatures[1].push_back(feature);
cannam@0 181 }
cannam@0 182
cannam@0 183 return returnFeatures;
cannam@0 184 }
cannam@0 185
cannam@0 186 SpectralCentroid::FeatureSet
cannam@0 187 SpectralCentroid::getRemainingFeatures()
cannam@0 188 {
cannam@0 189 return FeatureSet();
cannam@0 190 }
cannam@0 191