annotate examples/SpectralCentroid.cpp @ 287:f3b1ba71a305

* When calculating timestamps in order to write them into features that previously lacked them, from a buffering adapter, we need to take into account any timestamp adjustment used by other wrappers that are being wrapped by this one (i.e. input domain adapter)
author cannam
date Thu, 10 Sep 2009 15:21:34 +0000
parents 91574fc544db
children c97e70ed5abc
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@286 46 #ifdef __SUNPRO_CC
cannam@286 47 #include <sunmath.h>
cannam@286 48 #endif
cannam@286 49
cannam@210 50 #ifdef WIN32
cannam@210 51 #define isnan(x) false
cannam@210 52 #define isinf(x) false
cannam@210 53 #endif
cannam@0 54
cannam@0 55 SpectralCentroid::SpectralCentroid(float inputSampleRate) :
cannam@0 56 Plugin(inputSampleRate),
cannam@0 57 m_stepSize(0),
cannam@21 58 m_blockSize(0)
cannam@0 59 {
cannam@0 60 }
cannam@0 61
cannam@0 62 SpectralCentroid::~SpectralCentroid()
cannam@0 63 {
cannam@0 64 }
cannam@0 65
cannam@0 66 string
cannam@49 67 SpectralCentroid::getIdentifier() const
cannam@0 68 {
cannam@0 69 return "spectralcentroid";
cannam@0 70 }
cannam@0 71
cannam@0 72 string
cannam@49 73 SpectralCentroid::getName() const
cannam@49 74 {
cannam@49 75 return "Spectral Centroid";
cannam@49 76 }
cannam@49 77
cannam@49 78 string
cannam@0 79 SpectralCentroid::getDescription() const
cannam@0 80 {
cannam@49 81 return "Calculate the centroid frequency of the spectrum of the input signal";
cannam@0 82 }
cannam@0 83
cannam@0 84 string
cannam@0 85 SpectralCentroid::getMaker() const
cannam@0 86 {
cannam@43 87 return "Vamp SDK Example Plugins";
cannam@0 88 }
cannam@0 89
cannam@0 90 int
cannam@0 91 SpectralCentroid::getPluginVersion() const
cannam@0 92 {
cannam@0 93 return 2;
cannam@0 94 }
cannam@0 95
cannam@0 96 string
cannam@0 97 SpectralCentroid::getCopyright() const
cannam@0 98 {
cannam@7 99 return "Freely redistributable (BSD license)";
cannam@0 100 }
cannam@0 101
cannam@0 102 bool
cannam@0 103 SpectralCentroid::initialise(size_t channels, size_t stepSize, size_t blockSize)
cannam@0 104 {
cannam@0 105 if (channels < getMinChannelCount() ||
cannam@0 106 channels > getMaxChannelCount()) return false;
cannam@0 107
cannam@0 108 m_stepSize = stepSize;
cannam@0 109 m_blockSize = blockSize;
cannam@0 110
cannam@0 111 return true;
cannam@0 112 }
cannam@0 113
cannam@0 114 void
cannam@0 115 SpectralCentroid::reset()
cannam@0 116 {
cannam@0 117 }
cannam@0 118
cannam@0 119 SpectralCentroid::OutputList
cannam@0 120 SpectralCentroid::getOutputDescriptors() const
cannam@0 121 {
cannam@0 122 OutputList list;
cannam@0 123
cannam@0 124 OutputDescriptor d;
cannam@49 125 d.identifier = "logcentroid";
cannam@49 126 d.name = "Log Frequency Centroid";
cannam@49 127 d.description = "Centroid of the log weighted frequency spectrum";
cannam@0 128 d.unit = "Hz";
cannam@9 129 d.hasFixedBinCount = true;
cannam@9 130 d.binCount = 1;
cannam@0 131 d.hasKnownExtents = false;
cannam@0 132 d.isQuantized = false;
cannam@0 133 d.sampleType = OutputDescriptor::OneSamplePerStep;
cannam@0 134 list.push_back(d);
cannam@0 135
cannam@49 136 d.identifier = "linearcentroid";
cannam@49 137 d.name = "Linear Frequency Centroid";
cannam@49 138 d.description = "Centroid of the linear frequency spectrum";
cannam@0 139 list.push_back(d);
cannam@0 140
cannam@0 141 return list;
cannam@0 142 }
cannam@0 143
cannam@0 144 SpectralCentroid::FeatureSet
cannam@190 145 SpectralCentroid::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
cannam@0 146 {
cannam@0 147 if (m_stepSize == 0) {
cannam@0 148 cerr << "ERROR: SpectralCentroid::process: "
cannam@0 149 << "SpectralCentroid has not been initialised"
cannam@0 150 << endl;
cannam@0 151 return FeatureSet();
cannam@0 152 }
cannam@0 153
cannam@0 154 double numLin = 0.0, numLog = 0.0, denom = 0.0;
cannam@0 155
cannam@47 156 for (size_t i = 1; i <= m_blockSize/2; ++i) {
cannam@0 157 double freq = (double(i) * m_inputSampleRate) / m_blockSize;
cannam@0 158 double real = inputBuffers[0][i*2];
cannam@0 159 double imag = inputBuffers[0][i*2 + 1];
cannam@243 160 double scalemag = sqrt(real * real + imag * imag) / (m_blockSize/2);
cannam@243 161 numLin += freq * scalemag;
cannam@243 162 numLog += log10f(freq) * scalemag;
cannam@243 163 denom += scalemag;
cannam@0 164 }
cannam@0 165
cannam@0 166 FeatureSet returnFeatures;
cannam@0 167
cannam@0 168 if (denom != 0.0) {
cannam@0 169 float centroidLin = float(numLin / denom);
cannam@19 170 float centroidLog = powf(10, float(numLog / denom));
cannam@47 171
cannam@0 172 Feature feature;
cannam@0 173 feature.hasTimestamp = false;
cannam@243 174
cannam@243 175 if (!isnan(centroidLog) && !isinf(centroidLog)) {
cannam@243 176 feature.values.push_back(centroidLog);
cannam@243 177 }
cannam@0 178 returnFeatures[0].push_back(feature);
cannam@47 179
cannam@243 180 feature.values.clear();
cannam@243 181 if (!isnan(centroidLin) && !isinf(centroidLin)) {
cannam@243 182 feature.values.push_back(centroidLin);
cannam@243 183 }
cannam@0 184 returnFeatures[1].push_back(feature);
cannam@0 185 }
cannam@0 186
cannam@0 187 return returnFeatures;
cannam@0 188 }
cannam@0 189
cannam@0 190 SpectralCentroid::FeatureSet
cannam@0 191 SpectralCentroid::getRemainingFeatures()
cannam@0 192 {
cannam@0 193 return FeatureSet();
cannam@0 194 }
cannam@0 195