plugins/{Mfcc,MelEnergy}.cpp: fix mel filters to 40 for now, improve description
[vamp-aubio-plugins.git] / plugins / Mfcc.cpp
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2
3 /*
4     Vamp feature extraction plugins using Paul Brossier's Aubio library.
5
6     Copyright (C) 2006-2015 Paul Brossier <piem@aubio.org>
7
8     This file is part of vamp-aubio.
9
10     vamp-aubio is free software: you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation, either version 3 of the License, or
13     (at your option) any later version.
14
15     vamp-aubio is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19
20     You should have received a copy of the GNU General Public License
21     along with aubio.  If not, see <http://www.gnu.org/licenses/>.
22
23 */
24
25 #include <math.h>
26 #include "Mfcc.h"
27
28 using std::string;
29 using std::vector;
30 using std::cerr;
31 using std::endl;
32
33 Mfcc::Mfcc(float inputSampleRate) :
34     Plugin(inputSampleRate),
35     m_ibuf(0),      // input fvec_t, set in initialise
36     m_pvoc(0),      // aubio_pvoc_t, set in reset
37     m_ispec(0),     // cvec_t, set in initialise
38     m_mfcc(0),      // aubio_mfcc_t, set in reset
39     m_ovec(0),      // output fvec_t, set in initialise
40     m_nfilters(40), // parameter
41     m_ncoeffs(13),  // parameter
42     m_stepSize(0),  // host parameter
43     m_blockSize(0)  // host parameter
44 {
45 }
46
47 Mfcc::~Mfcc()
48 {
49     if (m_mfcc) del_aubio_mfcc(m_mfcc);
50     if (m_pvoc) del_aubio_pvoc(m_pvoc);
51     if (m_ibuf) del_fvec(m_ibuf);
52     if (m_ispec) del_cvec(m_ispec);
53     if (m_ovec) del_fvec(m_ovec);
54 }
55
56 string
57 Mfcc::getIdentifier() const
58 {
59     return "aubiomfcc";
60 }
61
62 string
63 Mfcc::getName() const
64 {
65     return "Aubio Mfcc Extractor";
66 }
67
68 string
69 Mfcc::getDescription() const
70 {
71     return "Extract Mel-Frequency Cepstrum Coefficients";
72 }
73
74 string
75 Mfcc::getMaker() const
76 {
77     return "Paul Brossier";
78 }
79
80 int
81 Mfcc::getPluginVersion() const
82 {
83     return 3;
84 }
85
86 string
87 Mfcc::getCopyright() const
88 {
89     return "GPL";
90 }
91
92 bool
93 Mfcc::initialise(size_t channels, size_t stepSize, size_t blockSize)
94 {
95     if (channels != 1) {
96         std::cerr << "Mfcc::initialise: channels must be 1" << std::endl;
97         return false;
98     }
99
100     m_stepSize = stepSize;
101     m_blockSize = blockSize;
102
103     m_ibuf = new_fvec(stepSize);
104     m_ispec = new_cvec(blockSize);
105     m_ovec = new_fvec(m_ncoeffs);
106
107     reset();
108
109     return true;
110 }
111
112 void
113 Mfcc::reset()
114 {
115     if (m_pvoc) del_aubio_pvoc(m_pvoc);
116     if (m_mfcc) del_aubio_mfcc(m_mfcc);
117
118     m_pvoc = new_aubio_pvoc(m_blockSize, m_stepSize);
119
120     m_mfcc = new_aubio_mfcc(m_blockSize, m_nfilters, m_ncoeffs,
121             lrintf(m_inputSampleRate));
122
123 }
124
125 size_t
126 Mfcc::getPreferredStepSize() const
127 {
128     return 128;
129 }
130
131 size_t
132 Mfcc::getPreferredBlockSize() const
133 {
134     return 512;
135 }
136
137 Mfcc::ParameterList
138 Mfcc::getParameterDescriptors() const
139 {
140     ParameterList list;
141
142     ParameterDescriptor desc;
143     desc.identifier = "nfilters";
144     desc.name = "Number of filters";
145     desc.description = "Size of mel filterbank used to compute MFCCs (fixed to 40 for now)";
146     desc.minValue = 40;
147     desc.maxValue = 40;
148     desc.defaultValue = 40;
149     desc.isQuantized = true;
150     desc.quantizeStep = 1;
151     list.push_back(desc);
152
153     desc = ParameterDescriptor();
154     desc.identifier = "ncoeffs";
155     desc.name = "Number of coefficients";
156     desc.description = "Number of output coefficients to compute";
157     desc.minValue = 1;
158     desc.maxValue = 100;
159     desc.defaultValue = 13;
160     desc.isQuantized = true;
161     desc.quantizeStep = 1;
162     list.push_back(desc);
163
164     return list;
165 }
166
167 float
168 Mfcc::getParameter(std::string param) const
169 {
170     if (param == "ncoeffs") {
171         return m_ncoeffs;
172     } else if (param == "nfilters") {
173         return m_nfilters;
174     } else {
175         return 0.0;
176     }
177 }
178
179 void
180 Mfcc::setParameter(std::string param, float value)
181 {
182     if (param == "nfilters") {
183         m_nfilters = lrintf(value);
184     } else if (param == "ncoeffs") {
185         m_ncoeffs = lrintf(value);
186     }
187 }
188
189 Mfcc::OutputList
190 Mfcc::getOutputDescriptors() const
191 {
192     OutputList list;
193
194     OutputDescriptor d;
195     d.identifier = "mfcc";
196     d.name = "Mel-Frequency Cepstrum Coefficients";
197     d.description = "List of detected Mel-Frequency Cepstrum Coefficients";
198     d.unit = "";
199     d.hasFixedBinCount = true;
200     d.binCount = m_ncoeffs;
201     d.isQuantized = true;
202     d.sampleType = OutputDescriptor::FixedSampleRate;
203     d.sampleRate = m_inputSampleRate / m_stepSize;
204     list.push_back(d);
205
206     return list;
207 }
208
209 Mfcc::FeatureSet
210 Mfcc::process(const float *const *inputBuffers,
211                Vamp::RealTime timestamp)
212 {
213     FeatureSet returnFeatures;
214
215     if (m_stepSize == 0) {
216         std::cerr << "Mfcc::process: Mfcc plugin not initialised" << std::endl;
217         return returnFeatures;
218     }
219     if (m_ncoeffs == 0) {
220         std::cerr << "Mfcc::process: Mfcc plugin not initialised" << std::endl;
221         return returnFeatures;
222     }
223
224     for (size_t i = 0; i < m_stepSize; ++i) {
225         fvec_set_sample(m_ibuf, inputBuffers[0][i], i);
226     }
227
228     aubio_pvoc_do(m_pvoc, m_ibuf, m_ispec);
229     aubio_mfcc_do(m_mfcc, m_ispec, m_ovec);
230
231     Feature feature;
232     //feature.hasTimestamp = false;
233     feature.timestamp = timestamp;
234     for (uint_t i = 0; i < m_ovec->length; i++) {
235         float value = m_ovec->data[i];
236         feature.values.push_back(value);
237     }
238
239     returnFeatures[0].push_back(feature);
240     return returnFeatures;
241 }
242
243 Mfcc::FeatureSet
244 Mfcc::getRemainingFeatures()
245 {
246     return FeatureSet();
247 }
248