Chris@161
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@161
|
2
|
Chris@161
|
3 /*
|
Chris@161
|
4 Silvet
|
Chris@161
|
5
|
Chris@161
|
6 A Vamp plugin for note transcription.
|
Chris@161
|
7 Centre for Digital Music, Queen Mary University of London.
|
Chris@161
|
8
|
Chris@161
|
9 This program is free software; you can redistribute it and/or
|
Chris@161
|
10 modify it under the terms of the GNU General Public License as
|
Chris@161
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@161
|
12 License, or (at your option) any later version. See the file
|
Chris@161
|
13 COPYING included with this distribution for more information.
|
Chris@161
|
14 */
|
Chris@161
|
15
|
Chris@161
|
16 #include "Instruments.h"
|
Chris@161
|
17
|
Chris@161
|
18 #include "data/include/templates.h"
|
Chris@161
|
19
|
Chris@161
|
20 #include <iostream>
|
Chris@161
|
21
|
Chris@161
|
22 using std::string;
|
Chris@161
|
23 using std::vector;
|
Chris@161
|
24 using std::cerr;
|
Chris@161
|
25 using std::endl;
|
Chris@161
|
26
|
Chris@298
|
27 InstrumentPack::InstrumentPack(int lowest, int highest,
|
Chris@298
|
28 std::string n, std::vector<Templates> tt) :
|
Chris@298
|
29 templateNoteCount(SILVET_TEMPLATE_NOTE_COUNT),
|
Chris@298
|
30 templateHeight(SILVET_TEMPLATE_HEIGHT),
|
Chris@298
|
31 templateMaxShift(SILVET_TEMPLATE_MAX_SHIFT),
|
Chris@298
|
32 templateSize(SILVET_TEMPLATE_SIZE),
|
Chris@298
|
33 lowestNote(lowest),
|
Chris@298
|
34 highestNote(highest),
|
Chris@298
|
35 maxPolyphony(5),
|
Chris@298
|
36 pitchSparsity(1.1),
|
Chris@298
|
37 sourceSparsity(1.2),
|
Chris@298
|
38 levelThreshold(5),
|
Chris@298
|
39 name(n),
|
Chris@298
|
40 templates(tt)
|
Chris@298
|
41 {
|
Chris@298
|
42 }
|
Chris@298
|
43
|
Chris@161
|
44 const char *simpleInstruments[] = {
|
Chris@176
|
45 // Each instrument has two consecutive slots, one for the pack
|
Chris@176
|
46 // name and one for the template to look up
|
Chris@161
|
47 "Guitar", "guitar",
|
Chris@161
|
48 "Violin", "violin",
|
Chris@220
|
49 "Viola", "viola",
|
Chris@161
|
50 "Cello", "cello",
|
Chris@161
|
51 "Horn", "horn",
|
Chris@161
|
52 "Flute", "flute",
|
Chris@161
|
53 "Oboe", "oboe",
|
Chris@161
|
54 "Clarinet", "clarinet",
|
Chris@161
|
55 "Tenor Sax", "tenorsax",
|
Chris@161
|
56 "Bassoon", "bassoon",
|
Chris@161
|
57 };
|
Chris@161
|
58
|
Chris@176
|
59 static bool
|
Chris@220
|
60 isBowedString(int i)
|
Chris@176
|
61 {
|
Chris@176
|
62 string tname(simpleInstruments[i+1]);
|
Chris@176
|
63 return tname == "violin"
|
Chris@220
|
64 || tname == "viola"
|
Chris@176
|
65 || tname == "cello"
|
Chris@176
|
66 ;
|
Chris@176
|
67 }
|
Chris@176
|
68
|
Chris@176
|
69 static bool
|
Chris@176
|
70 isWind(int i)
|
Chris@176
|
71 {
|
Chris@176
|
72 string tname(simpleInstruments[i+1]);
|
Chris@176
|
73 return tname == "horn"
|
Chris@176
|
74 || tname == "flute"
|
Chris@176
|
75 || tname == "oboe"
|
Chris@176
|
76 || tname == "clarinet"
|
Chris@176
|
77 || tname == "tenorsax"
|
Chris@176
|
78 || tname == "bassoon"
|
Chris@176
|
79 ;
|
Chris@176
|
80 }
|
Chris@176
|
81
|
Chris@161
|
82 static InstrumentPack::Templates
|
Chris@161
|
83 templatesFor(string name)
|
Chris@161
|
84 {
|
Chris@161
|
85 for (int i = 0; i < SILVET_TEMPLATE_COUNT; ++i) {
|
Chris@161
|
86
|
Chris@161
|
87 if (string(silvet_templates[i].name) == name) {
|
Chris@161
|
88
|
Chris@161
|
89 silvet_template_t *t = &silvet_templates[i];
|
Chris@161
|
90
|
Chris@161
|
91 InstrumentPack::Templates rt;
|
Chris@161
|
92 rt.lowestNote = t->lowest;
|
Chris@161
|
93 rt.highestNote = t->highest;
|
Chris@161
|
94 rt.data = vector<vector<float> >
|
Chris@161
|
95 (SILVET_TEMPLATE_NOTE_COUNT,
|
Chris@161
|
96 vector<float>(SILVET_TEMPLATE_SIZE, 0.f));
|
Chris@161
|
97
|
Chris@161
|
98 for (int j = 0; j < SILVET_TEMPLATE_NOTE_COUNT; ++j) {
|
Chris@161
|
99 for (int k = 0; k < SILVET_TEMPLATE_SIZE; ++k) {
|
Chris@161
|
100 rt.data[j][k] = t->data[j][k];
|
Chris@161
|
101 }
|
Chris@161
|
102 }
|
Chris@161
|
103
|
Chris@161
|
104 return rt;
|
Chris@161
|
105 }
|
Chris@161
|
106 }
|
Chris@161
|
107
|
Chris@161
|
108 return InstrumentPack::Templates();
|
Chris@161
|
109 }
|
Chris@161
|
110
|
Chris@161
|
111 static bool
|
Chris@161
|
112 isOK(InstrumentPack &d)
|
Chris@161
|
113 {
|
Chris@161
|
114 if (d.name == "") {
|
Chris@161
|
115 cerr << "ERROR: Silvet::InstrumentPack: Empty name in instrument definition" << endl;
|
Chris@161
|
116 return false;
|
Chris@161
|
117 }
|
Chris@161
|
118 if (d.templates.empty()) {
|
Chris@161
|
119 cerr << "ERROR: Silvet::InstrumentPack: Instrument definition \"" << d.name << "\" contains no templates!" << endl;
|
Chris@161
|
120 return false;
|
Chris@161
|
121 }
|
Chris@161
|
122 for (int i = 0; i < int(d.templates.size()); ++i) {
|
Chris@161
|
123 if (d.templates[i].data.empty()) {
|
Chris@161
|
124 cerr << "ERROR: Silvet::InstrumentPack: Instrument definition \"" << d.name << "\" contains one or more empty templates!" << endl;
|
Chris@161
|
125 return false;
|
Chris@161
|
126 }
|
Chris@161
|
127 }
|
Chris@161
|
128 return true;
|
Chris@161
|
129 }
|
Chris@161
|
130
|
Chris@161
|
131 vector<InstrumentPack>
|
Chris@161
|
132 InstrumentPack::listInstrumentPacks()
|
Chris@161
|
133 {
|
Chris@161
|
134 vector<InstrumentPack> ii;
|
Chris@161
|
135
|
Chris@161
|
136 vector<Templates> allTemplates;
|
Chris@161
|
137 allTemplates.push_back(templatesFor("piano1"));
|
Chris@161
|
138
|
Chris@161
|
139 vector<Templates> pianoTemplates;
|
Chris@161
|
140 pianoTemplates.push_back(templatesFor("piano1"));
|
Chris@161
|
141 pianoTemplates.push_back(templatesFor("piano2"));
|
Chris@161
|
142 pianoTemplates.push_back(templatesFor("piano3"));
|
Chris@220
|
143 pianoTemplates.push_back(templatesFor("pianorwc"));
|
Chris@161
|
144 InstrumentPack piano(silvet_templates_lowest_note,
|
Chris@161
|
145 silvet_templates_highest_note,
|
Chris@161
|
146 "Piano",
|
Chris@161
|
147 pianoTemplates);
|
Chris@266
|
148 piano.maxPolyphony = 6;
|
Chris@339
|
149 piano.levelThreshold = 5;
|
Chris@213
|
150 piano.pitchSparsity = 1.0;
|
Chris@213
|
151 piano.sourceSparsity = 1.0;
|
Chris@161
|
152 if (isOK(piano)) {
|
Chris@161
|
153 ii.push_back(piano);
|
Chris@161
|
154 }
|
Chris@161
|
155
|
Chris@176
|
156 vector<Templates> stringTemplates;
|
Chris@176
|
157 vector<Templates> windTemplates;
|
Chris@176
|
158
|
Chris@161
|
159 for (int i = 0;
|
Chris@161
|
160 i < int(sizeof(simpleInstruments)/sizeof(simpleInstruments[0]));
|
Chris@161
|
161 i += 2) {
|
Chris@213
|
162
|
Chris@161
|
163 vector<Templates> tt;
|
Chris@161
|
164 Templates t = templatesFor(simpleInstruments[i+1]);
|
Chris@161
|
165 tt.push_back(t);
|
Chris@161
|
166 allTemplates.push_back(t);
|
Chris@161
|
167 InstrumentPack instr(t.lowestNote,
|
Chris@161
|
168 t.highestNote,
|
Chris@161
|
169 simpleInstruments[i],
|
Chris@161
|
170 tt);
|
Chris@266
|
171
|
Chris@200
|
172 instr.maxPolyphony = 5;
|
Chris@200
|
173 instr.levelThreshold = 6;
|
Chris@266
|
174
|
Chris@220
|
175 if (isBowedString(i)) {
|
Chris@266
|
176 instr.maxPolyphony = 2;
|
Chris@268
|
177 instr.levelThreshold = 5;
|
Chris@183
|
178 stringTemplates.push_back(t);
|
Chris@183
|
179 }
|
Chris@183
|
180 if (isWind(i)) {
|
Chris@266
|
181 instr.maxPolyphony = 2;
|
Chris@183
|
182 windTemplates.push_back(t);
|
Chris@183
|
183 }
|
Chris@161
|
184 if (isOK(instr)) {
|
Chris@161
|
185 ii.push_back(instr);
|
Chris@161
|
186 }
|
Chris@161
|
187 }
|
Chris@161
|
188
|
Chris@161
|
189 InstrumentPack all(silvet_templates_lowest_note,
|
Chris@161
|
190 silvet_templates_highest_note,
|
Chris@161
|
191 "Multiple or unknown instruments",
|
Chris@161
|
192 allTemplates);
|
Chris@183
|
193 all.maxPolyphony = 5;
|
Chris@268
|
194 all.levelThreshold = 6;
|
Chris@161
|
195 if (isOK(all)) {
|
Chris@161
|
196 ii.insert(ii.begin(), all);
|
Chris@161
|
197 }
|
Chris@161
|
198
|
Chris@176
|
199 InstrumentPack strings(silvet_templates_lowest_note, // cello
|
Chris@176
|
200 silvet_templates_highest_note, // violin
|
Chris@220
|
201 "String quartet",
|
Chris@176
|
202 stringTemplates);
|
Chris@340
|
203 strings.maxPolyphony = 6;
|
Chris@340
|
204 strings.levelThreshold = 3;
|
Chris@176
|
205 if (isOK(strings)) {
|
Chris@176
|
206 ii.push_back(strings);
|
Chris@176
|
207 }
|
Chris@176
|
208
|
Chris@176
|
209 InstrumentPack winds(silvet_templates_lowest_note, // basson
|
Chris@176
|
210 silvet_templates_highest_note, // flute
|
Chris@176
|
211 "Wind ensemble",
|
Chris@176
|
212 windTemplates);
|
Chris@183
|
213 winds.maxPolyphony = 5;
|
Chris@183
|
214 winds.levelThreshold = 5;
|
Chris@176
|
215 if (isOK(winds)) {
|
Chris@176
|
216 ii.push_back(winds);
|
Chris@176
|
217 }
|
Chris@176
|
218
|
Chris@161
|
219 return ii;
|
Chris@161
|
220 }
|
Chris@161
|
221
|