Chris@31
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@31
|
2
|
Chris@31
|
3 /*
|
Chris@31
|
4 Silvet
|
Chris@31
|
5
|
Chris@31
|
6 A Vamp plugin for note transcription.
|
Chris@31
|
7 Centre for Digital Music, Queen Mary University of London.
|
Chris@31
|
8
|
Chris@31
|
9 This program is free software; you can redistribute it and/or
|
Chris@31
|
10 modify it under the terms of the GNU General Public License as
|
Chris@31
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@31
|
12 License, or (at your option) any later version. See the file
|
Chris@31
|
13 COPYING included with this distribution for more information.
|
Chris@31
|
14 */
|
Chris@31
|
15
|
Chris@31
|
16 #include "Silvet.h"
|
Chris@31
|
17
|
Chris@31
|
18 #include "data/include/templates.h"
|
Chris@31
|
19
|
Chris@31
|
20 #include "dsp/rateconversion/Resampler.h"
|
Chris@31
|
21
|
Chris@31
|
22 #include "constant-q-cpp/cpp-qm-dsp/ConstantQ.h"
|
Chris@31
|
23
|
Chris@31
|
24 #include <vector>
|
Chris@31
|
25
|
Chris@31
|
26 using std::vector;
|
Chris@31
|
27 using std::cerr;
|
Chris@31
|
28 using std::endl;
|
Chris@31
|
29
|
Chris@31
|
30 static int processingSampleRate = 44100;
|
Chris@31
|
31 static int processingBPO = 60;
|
Chris@31
|
32
|
Chris@31
|
33
|
Chris@31
|
34 Silvet::Silvet(float inputSampleRate) :
|
Chris@31
|
35 Plugin(inputSampleRate),
|
Chris@31
|
36 m_resampler(0),
|
Chris@31
|
37 m_cq(0)
|
Chris@31
|
38 {
|
Chris@31
|
39 }
|
Chris@31
|
40
|
Chris@31
|
41 Silvet::~Silvet()
|
Chris@31
|
42 {
|
Chris@31
|
43 delete m_resampler;
|
Chris@31
|
44 delete m_cq;
|
Chris@31
|
45 }
|
Chris@31
|
46
|
Chris@31
|
47 string
|
Chris@31
|
48 Silvet::getIdentifier() const
|
Chris@31
|
49 {
|
Chris@31
|
50 return "silvet";
|
Chris@31
|
51 }
|
Chris@31
|
52
|
Chris@31
|
53 string
|
Chris@31
|
54 Silvet::getName() const
|
Chris@31
|
55 {
|
Chris@31
|
56 return "Silvet Note Transcription";
|
Chris@31
|
57 }
|
Chris@31
|
58
|
Chris@31
|
59 string
|
Chris@31
|
60 Silvet::getDescription() const
|
Chris@31
|
61 {
|
Chris@31
|
62 // Return something helpful here!
|
Chris@31
|
63 return "";
|
Chris@31
|
64 }
|
Chris@31
|
65
|
Chris@31
|
66 string
|
Chris@31
|
67 Silvet::getMaker() const
|
Chris@31
|
68 {
|
Chris@31
|
69 // Your name here
|
Chris@31
|
70 return "";
|
Chris@31
|
71 }
|
Chris@31
|
72
|
Chris@31
|
73 int
|
Chris@31
|
74 Silvet::getPluginVersion() const
|
Chris@31
|
75 {
|
Chris@31
|
76 return 1;
|
Chris@31
|
77 }
|
Chris@31
|
78
|
Chris@31
|
79 string
|
Chris@31
|
80 Silvet::getCopyright() const
|
Chris@31
|
81 {
|
Chris@31
|
82 // This function is not ideally named. It does not necessarily
|
Chris@31
|
83 // need to say who made the plugin -- getMaker does that -- but it
|
Chris@31
|
84 // should indicate the terms under which it is distributed. For
|
Chris@31
|
85 // example, "Copyright (year). All Rights Reserved", or "GPL"
|
Chris@31
|
86 return "";
|
Chris@31
|
87 }
|
Chris@31
|
88
|
Chris@31
|
89 Silvet::InputDomain
|
Chris@31
|
90 Silvet::getInputDomain() const
|
Chris@31
|
91 {
|
Chris@31
|
92 return TimeDomain;
|
Chris@31
|
93 }
|
Chris@31
|
94
|
Chris@31
|
95 size_t
|
Chris@31
|
96 Silvet::getPreferredBlockSize() const
|
Chris@31
|
97 {
|
Chris@31
|
98 return 0;
|
Chris@31
|
99 }
|
Chris@31
|
100
|
Chris@31
|
101 size_t
|
Chris@31
|
102 Silvet::getPreferredStepSize() const
|
Chris@31
|
103 {
|
Chris@31
|
104 return 0;
|
Chris@31
|
105 }
|
Chris@31
|
106
|
Chris@31
|
107 size_t
|
Chris@31
|
108 Silvet::getMinChannelCount() const
|
Chris@31
|
109 {
|
Chris@31
|
110 return 1;
|
Chris@31
|
111 }
|
Chris@31
|
112
|
Chris@31
|
113 size_t
|
Chris@31
|
114 Silvet::getMaxChannelCount() const
|
Chris@31
|
115 {
|
Chris@31
|
116 return 1;
|
Chris@31
|
117 }
|
Chris@31
|
118
|
Chris@31
|
119 Silvet::ParameterList
|
Chris@31
|
120 Silvet::getParameterDescriptors() const
|
Chris@31
|
121 {
|
Chris@31
|
122 ParameterList list;
|
Chris@31
|
123 return list;
|
Chris@31
|
124 }
|
Chris@31
|
125
|
Chris@31
|
126 float
|
Chris@31
|
127 Silvet::getParameter(string identifier) const
|
Chris@31
|
128 {
|
Chris@31
|
129 return 0;
|
Chris@31
|
130 }
|
Chris@31
|
131
|
Chris@31
|
132 void
|
Chris@31
|
133 Silvet::setParameter(string identifier, float value)
|
Chris@31
|
134 {
|
Chris@31
|
135 }
|
Chris@31
|
136
|
Chris@31
|
137 Silvet::ProgramList
|
Chris@31
|
138 Silvet::getPrograms() const
|
Chris@31
|
139 {
|
Chris@31
|
140 ProgramList list;
|
Chris@31
|
141 return list;
|
Chris@31
|
142 }
|
Chris@31
|
143
|
Chris@31
|
144 string
|
Chris@31
|
145 Silvet::getCurrentProgram() const
|
Chris@31
|
146 {
|
Chris@31
|
147 return "";
|
Chris@31
|
148 }
|
Chris@31
|
149
|
Chris@31
|
150 void
|
Chris@31
|
151 Silvet::selectProgram(string name)
|
Chris@31
|
152 {
|
Chris@31
|
153 }
|
Chris@31
|
154
|
Chris@31
|
155 Silvet::OutputList
|
Chris@31
|
156 Silvet::getOutputDescriptors() const
|
Chris@31
|
157 {
|
Chris@31
|
158 OutputList list;
|
Chris@31
|
159
|
Chris@31
|
160 OutputDescriptor d;
|
Chris@31
|
161 d.identifier = "transcription";
|
Chris@31
|
162 d.name = "Transcription";
|
Chris@31
|
163 d.description = ""; //!!!
|
Chris@31
|
164 d.unit = "Hz";
|
Chris@31
|
165 d.hasFixedBinCount = true;
|
Chris@31
|
166 d.binCount = 2;
|
Chris@31
|
167 d.binNames.push_back("Frequency");
|
Chris@31
|
168 d.binNames.push_back("Velocity");
|
Chris@31
|
169 d.hasKnownExtents = false;
|
Chris@31
|
170 d.isQuantized = false;
|
Chris@31
|
171 d.sampleType = OutputDescriptor::VariableSampleRate;
|
Chris@31
|
172 d.sampleRate = 0;
|
Chris@31
|
173 d.hasDuration = true;
|
Chris@31
|
174 list.push_back(d);
|
Chris@31
|
175
|
Chris@31
|
176 return list;
|
Chris@31
|
177 }
|
Chris@31
|
178
|
Chris@31
|
179 bool
|
Chris@31
|
180 Silvet::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
Chris@31
|
181 {
|
Chris@31
|
182 if (channels < getMinChannelCount() ||
|
Chris@31
|
183 channels > getMaxChannelCount()) return false;
|
Chris@31
|
184
|
Chris@31
|
185 if (stepSize != blockSize) {
|
Chris@31
|
186 cerr << "Silvet::initialise: Step size must be the same as block size ("
|
Chris@31
|
187 << stepSize << " != " << blockSize << ")" << endl;
|
Chris@31
|
188 return false;
|
Chris@31
|
189 }
|
Chris@31
|
190
|
Chris@31
|
191 m_blockSize = blockSize;
|
Chris@31
|
192
|
Chris@31
|
193 reset();
|
Chris@31
|
194
|
Chris@31
|
195 return true;
|
Chris@31
|
196 }
|
Chris@31
|
197
|
Chris@31
|
198 void
|
Chris@31
|
199 Silvet::reset()
|
Chris@31
|
200 {
|
Chris@31
|
201 delete m_resampler;
|
Chris@31
|
202 delete m_cq;
|
Chris@31
|
203
|
Chris@31
|
204 if (m_inputSampleRate != processingSampleRate) {
|
Chris@31
|
205 m_resampler = new Resampler(m_inputSampleRate, processingSampleRate);
|
Chris@31
|
206 } else {
|
Chris@31
|
207 m_resampler = 0;
|
Chris@31
|
208 }
|
Chris@31
|
209
|
Chris@31
|
210 m_cq = new ConstantQ
|
Chris@31
|
211 (processingSampleRate, 27.5, processingSampleRate / 3, processingBPO);
|
Chris@31
|
212
|
Chris@31
|
213 }
|
Chris@31
|
214
|
Chris@31
|
215 Silvet::FeatureSet
|
Chris@31
|
216 Silvet::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
|
Chris@31
|
217 {
|
Chris@31
|
218 vector<double> data;
|
Chris@31
|
219 for (int i = 0; i < m_blockSize; ++i) data.push_back(inputBuffers[0][i]);
|
Chris@31
|
220
|
Chris@31
|
221 if (m_resampler) {
|
Chris@31
|
222 data = m_resampler->process(data.data(), data.size());
|
Chris@31
|
223 }
|
Chris@31
|
224
|
Chris@31
|
225 vector<vector<double> > cqout = m_cq->process(data);
|
Chris@31
|
226
|
Chris@31
|
227 return FeatureSet();
|
Chris@31
|
228 }
|
Chris@31
|
229
|
Chris@31
|
230 Silvet::FeatureSet
|
Chris@31
|
231 Silvet::getRemainingFeatures()
|
Chris@31
|
232 {
|
Chris@31
|
233
|
Chris@31
|
234 return FeatureSet();
|
Chris@31
|
235 }
|
Chris@31
|
236
|