annotate src/Instruments.cpp @ 265:8788fe838c49 norm

Using all piano templates on unknown instrument slows things down a lot, and doesn't seem all that helpful
author Chris Cannam
date Wed, 23 Jul 2014 15:44:13 +0100
parents 81288afddf43
children c9d2809cb86d
rev   line source
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 const int InstrumentPack::templateNoteCount = SILVET_TEMPLATE_NOTE_COUNT;
Chris@161 23 const int InstrumentPack::templateHeight = SILVET_TEMPLATE_HEIGHT;
Chris@161 24 const int InstrumentPack::templateMaxShift = SILVET_TEMPLATE_MAX_SHIFT;
Chris@161 25 const int InstrumentPack::templateSize = SILVET_TEMPLATE_SIZE;
Chris@161 26
Chris@161 27 using std::string;
Chris@161 28 using std::vector;
Chris@161 29 using std::cerr;
Chris@161 30 using std::endl;
Chris@161 31
Chris@161 32 const char *simpleInstruments[] = {
Chris@176 33 // Each instrument has two consecutive slots, one for the pack
Chris@176 34 // name and one for the template to look up
Chris@161 35 "Guitar", "guitar",
Chris@161 36 "Violin", "violin",
Chris@220 37 "Viola", "viola",
Chris@161 38 "Cello", "cello",
Chris@161 39 "Horn", "horn",
Chris@161 40 "Flute", "flute",
Chris@161 41 "Oboe", "oboe",
Chris@161 42 "Clarinet", "clarinet",
Chris@161 43 "Tenor Sax", "tenorsax",
Chris@161 44 "Bassoon", "bassoon",
Chris@161 45 };
Chris@161 46
Chris@176 47 static bool
Chris@220 48 isBowedString(int i)
Chris@176 49 {
Chris@176 50 string tname(simpleInstruments[i+1]);
Chris@176 51 return tname == "violin"
Chris@220 52 || tname == "viola"
Chris@176 53 || tname == "cello"
Chris@176 54 ;
Chris@176 55 }
Chris@176 56
Chris@176 57 static bool
Chris@176 58 isWind(int i)
Chris@176 59 {
Chris@176 60 string tname(simpleInstruments[i+1]);
Chris@176 61 return tname == "horn"
Chris@176 62 || tname == "flute"
Chris@176 63 || tname == "oboe"
Chris@176 64 || tname == "clarinet"
Chris@176 65 || tname == "tenorsax"
Chris@176 66 || tname == "bassoon"
Chris@176 67 ;
Chris@176 68 }
Chris@176 69
Chris@161 70 static InstrumentPack::Templates
Chris@161 71 templatesFor(string name)
Chris@161 72 {
Chris@161 73 for (int i = 0; i < SILVET_TEMPLATE_COUNT; ++i) {
Chris@161 74
Chris@161 75 if (string(silvet_templates[i].name) == name) {
Chris@161 76
Chris@161 77 silvet_template_t *t = &silvet_templates[i];
Chris@161 78
Chris@161 79 InstrumentPack::Templates rt;
Chris@161 80 rt.lowestNote = t->lowest;
Chris@161 81 rt.highestNote = t->highest;
Chris@161 82 rt.data = vector<vector<float> >
Chris@161 83 (SILVET_TEMPLATE_NOTE_COUNT,
Chris@161 84 vector<float>(SILVET_TEMPLATE_SIZE, 0.f));
Chris@161 85
Chris@161 86 for (int j = 0; j < SILVET_TEMPLATE_NOTE_COUNT; ++j) {
Chris@161 87 for (int k = 0; k < SILVET_TEMPLATE_SIZE; ++k) {
Chris@161 88 rt.data[j][k] = t->data[j][k];
Chris@161 89 }
Chris@161 90 }
Chris@161 91
Chris@161 92 return rt;
Chris@161 93 }
Chris@161 94 }
Chris@161 95
Chris@161 96 return InstrumentPack::Templates();
Chris@161 97 }
Chris@161 98
Chris@161 99 static bool
Chris@161 100 isOK(InstrumentPack &d)
Chris@161 101 {
Chris@161 102 if (d.name == "") {
Chris@161 103 cerr << "ERROR: Silvet::InstrumentPack: Empty name in instrument definition" << endl;
Chris@161 104 return false;
Chris@161 105 }
Chris@161 106 if (d.templates.empty()) {
Chris@161 107 cerr << "ERROR: Silvet::InstrumentPack: Instrument definition \"" << d.name << "\" contains no templates!" << endl;
Chris@161 108 return false;
Chris@161 109 }
Chris@161 110 for (int i = 0; i < int(d.templates.size()); ++i) {
Chris@161 111 if (d.templates[i].data.empty()) {
Chris@161 112 cerr << "ERROR: Silvet::InstrumentPack: Instrument definition \"" << d.name << "\" contains one or more empty templates!" << endl;
Chris@161 113 return false;
Chris@161 114 }
Chris@161 115 }
Chris@161 116 return true;
Chris@161 117 }
Chris@161 118
Chris@161 119 vector<InstrumentPack>
Chris@161 120 InstrumentPack::listInstrumentPacks()
Chris@161 121 {
Chris@161 122 vector<InstrumentPack> ii;
Chris@161 123
Chris@161 124 vector<Templates> allTemplates;
Chris@161 125 allTemplates.push_back(templatesFor("piano1"));
Chris@161 126
Chris@161 127 vector<Templates> pianoTemplates;
Chris@161 128 pianoTemplates.push_back(templatesFor("piano1"));
Chris@161 129 pianoTemplates.push_back(templatesFor("piano2"));
Chris@161 130 pianoTemplates.push_back(templatesFor("piano3"));
Chris@220 131 pianoTemplates.push_back(templatesFor("pianorwc"));
Chris@161 132 InstrumentPack piano(silvet_templates_lowest_note,
Chris@161 133 silvet_templates_highest_note,
Chris@161 134 "Piano",
Chris@161 135 pianoTemplates);
Chris@200 136 // piano.maxPolyphony = 8;
Chris@213 137 // piano.levelThreshold = 4;
Chris@200 138 piano.maxPolyphony = 5;
Chris@200 139 piano.levelThreshold = 6;
Chris@213 140 piano.pitchSparsity = 1.0;
Chris@213 141 piano.sourceSparsity = 1.0;
Chris@161 142 if (isOK(piano)) {
Chris@161 143 ii.push_back(piano);
Chris@161 144 }
Chris@161 145
Chris@176 146 vector<Templates> stringTemplates;
Chris@176 147 vector<Templates> windTemplates;
Chris@176 148
Chris@161 149 for (int i = 0;
Chris@161 150 i < int(sizeof(simpleInstruments)/sizeof(simpleInstruments[0]));
Chris@161 151 i += 2) {
Chris@213 152
Chris@161 153 vector<Templates> tt;
Chris@161 154 Templates t = templatesFor(simpleInstruments[i+1]);
Chris@161 155 tt.push_back(t);
Chris@161 156 allTemplates.push_back(t);
Chris@161 157 InstrumentPack instr(t.lowestNote,
Chris@161 158 t.highestNote,
Chris@161 159 simpleInstruments[i],
Chris@161 160 tt);
Chris@200 161 // instr.pitchSparsity = 1.5;
Chris@200 162 instr.maxPolyphony = 5;
Chris@200 163 instr.levelThreshold = 6;
Chris@220 164 if (isBowedString(i)) {
Chris@200 165 // instr.maxPolyphony = 2;
Chris@200 166 // instr.levelThreshold = 3;
Chris@183 167 stringTemplates.push_back(t);
Chris@183 168 }
Chris@183 169 if (isWind(i)) {
Chris@200 170 // instr.maxPolyphony = 1;
Chris@200 171 // instr.levelThreshold = 5;
Chris@183 172 windTemplates.push_back(t);
Chris@183 173 }
Chris@161 174 if (isOK(instr)) {
Chris@161 175 ii.push_back(instr);
Chris@161 176 }
Chris@161 177 }
Chris@161 178
Chris@161 179 InstrumentPack all(silvet_templates_lowest_note,
Chris@161 180 silvet_templates_highest_note,
Chris@161 181 "Multiple or unknown instruments",
Chris@161 182 allTemplates);
Chris@183 183 all.maxPolyphony = 5;
Chris@183 184 all.levelThreshold = 6;//!!! but this does need to be a parameter too, or else we need to be able to detect very quiet stuff somehow
Chris@161 185 if (isOK(all)) {
Chris@161 186 ii.insert(ii.begin(), all);
Chris@161 187 }
Chris@161 188
Chris@176 189 InstrumentPack strings(silvet_templates_lowest_note, // cello
Chris@176 190 silvet_templates_highest_note, // violin
Chris@220 191 "String quartet",
Chris@176 192 stringTemplates);
Chris@183 193 strings.maxPolyphony = 5;
Chris@183 194 strings.levelThreshold = 3;
Chris@176 195 if (isOK(strings)) {
Chris@176 196 ii.push_back(strings);
Chris@176 197 }
Chris@176 198
Chris@176 199 InstrumentPack winds(silvet_templates_lowest_note, // basson
Chris@176 200 silvet_templates_highest_note, // flute
Chris@176 201 "Wind ensemble",
Chris@176 202 windTemplates);
Chris@183 203 winds.maxPolyphony = 5;
Chris@183 204 winds.levelThreshold = 5;
Chris@176 205 if (isOK(winds)) {
Chris@176 206 ii.push_back(winds);
Chris@176 207 }
Chris@176 208
Chris@161 209 return ii;
Chris@161 210 }
Chris@161 211