comparison Tuning.cpp @ 35:cf8898a0174c matthiasm-plugin

* Split out NNLSChroma plugin into three plugins (chroma, chordino, tuning) with a common base class. There's still quite a lot of duplication between the getRemainingFeatures functions. Also add copyright / copying headers, etc.
author Chris Cannam
date Fri, 22 Oct 2010 11:30:21 +0100
parents NNLSChroma.cpp@da3195577172
children 1d668695c03b
comparison
equal deleted inserted replaced
34:8edcf48f4031 35:cf8898a0174c
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 NNLS-Chroma / Chordino
5
6 Audio feature extraction plugins for chromagram and chord
7 estimation.
8
9 Centre for Digital Music, Queen Mary University of London.
10 This file copyright 2008-2010 Matthias Mauch and QMUL.
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version. See the file
16 COPYING included with this distribution for more information.
17 */
18
19 #include "Tuning.h"
20
21 #include "chromamethods.h"
22
23 #include <cstdlib>
24 #include <fstream>
25 #include <cmath>
26
27 #include <algorithm>
28
29 const bool debug_on = false;
30
31 const vector<float> hw(hammingwind, hammingwind+19);
32
33 Tuning::Tuning(float inputSampleRate) :
34 NNLSBase(inputSampleRate)
35 {
36 if (debug_on) cerr << "--> Tuning" << endl;
37 }
38
39 Tuning::~Tuning()
40 {
41 if (debug_on) cerr << "--> ~Tuning" << endl;
42 }
43
44 string
45 Tuning::getIdentifier() const
46 {
47 if (debug_on) cerr << "--> getIdentifier" << endl;
48 return "tuning";
49 }
50
51 string
52 Tuning::getName() const
53 {
54 if (debug_on) cerr << "--> getName" << endl;
55 return "Tuning";
56 }
57
58 string
59 Tuning::getDescription() const
60 {
61 // Return something helpful here!
62 if (debug_on) cerr << "--> getDescription" << endl;
63 return "This plugin provides a number of features derived from a log-frequency amplitude spectrum of the DFT: some variants of the log-frequency spectrum, including a semitone spectrum derived from approximate transcription using the NNLS algorithm; based on this semitone spectrum, chroma features and a simple chord estimate.";
64 }
65
66 Tuning::OutputList
67 Tuning::getOutputDescriptors() const
68 {
69 if (debug_on) cerr << "--> getOutputDescriptors" << endl;
70 OutputList list;
71
72 int index = 0;
73
74 OutputDescriptor d0;
75 d0.identifier = "tuning";
76 d0.name = "Tuning";
77 d0.description = "The concert pitch.";
78 d0.unit = "Hz";
79 d0.hasFixedBinCount = true;
80 d0.binCount = 0;
81 d0.hasKnownExtents = true;
82 d0.minValue = 427.47;
83 d0.maxValue = 452.89;
84 d0.isQuantized = false;
85 d0.sampleType = OutputDescriptor::VariableSampleRate;
86 d0.hasDuration = false;
87 list.push_back(d0);
88 m_outputTuning = index++;
89
90 OutputDescriptor d10;
91 d10.identifier = "localtuning";
92 d10.name = "Local tuning";
93 d10.description = "Tuning based on the history up to this timestamp.";
94 d10.unit = "Hz";
95 d10.hasFixedBinCount = true;
96 d10.binCount = 1;
97 d10.hasKnownExtents = true;
98 d10.minValue = 427.47;
99 d10.maxValue = 452.89;
100 d10.isQuantized = false;
101 d10.sampleType = OutputDescriptor::FixedSampleRate;
102 d10.hasDuration = false;
103 // d10.sampleRate = (m_stepSize == 0) ? m_inputSampleRate/2048 : m_inputSampleRate/m_stepSize;
104 list.push_back(d10);
105 m_outputLocalTuning = index++;
106
107 return list;
108 }
109
110
111 bool
112 Tuning::initialise(size_t channels, size_t stepSize, size_t blockSize)
113 {
114 if (debug_on) {
115 cerr << "--> initialise";
116 }
117
118 if (!NNLSBase::initialise(channels, stepSize, blockSize)) {
119 return false;
120 }
121
122 return true;
123 }
124
125 void
126 Tuning::reset()
127 {
128 if (debug_on) cerr << "--> reset";
129 NNLSBase::reset();
130 }
131
132 Tuning::FeatureSet
133 Tuning::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
134 {
135 if (debug_on) cerr << "--> process" << endl;
136
137 NNLSBase::baseProcess(inputBuffers, timestamp);
138
139 Feature f10; // local tuning
140 f10.hasTimestamp = true;
141 f10.timestamp = timestamp;
142 float normalisedtuning = m_localTuning[m_localTuning.size()-1];
143 float tuning440 = 440 * pow(2,normalisedtuning/12);
144 f10.values.push_back(tuning440);
145
146 FeatureSet fs;
147 fs[m_outputLocalTuning].push_back(f10);
148 return fs;
149 }
150
151 Tuning::FeatureSet
152 Tuning::getRemainingFeatures()
153 {
154 if (debug_on) cerr << "--> getRemainingFeatures" << endl;
155 FeatureSet fsOut;
156 if (m_logSpectrum.size() == 0) return fsOut;
157
158 //
159 /** Calculate Tuning
160 calculate tuning from (using the angle of the complex number defined by the
161 cumulative mean real and imag values)
162 **/
163 float meanTuningImag = sinvalue * m_meanTuning1 - sinvalue * m_meanTuning2;
164 float meanTuningReal = m_meanTuning0 + cosvalue * m_meanTuning1 + cosvalue * m_meanTuning2;
165 float cumulativetuning = 440 * pow(2,atan2(meanTuningImag, meanTuningReal)/(24*M_PI));
166
167 char buffer0 [50];
168
169 sprintf(buffer0, "estimated tuning: %0.1f Hz", cumulativetuning);
170
171 // push tuning to FeatureSet fsOut
172 Feature f0; // tuning
173 f0.hasTimestamp = true;
174 f0.timestamp = Vamp::RealTime::frame2RealTime(0, lrintf(m_inputSampleRate));;
175 f0.label = buffer0;
176 fsOut[m_outputTuning].push_back(f0);
177
178 return fsOut;
179
180 }
181