annotate src/Instruments.cpp @ 200:4840c6306b4f

Use same polyphony/threshold settings for all single instruments as for unknown/multiple instruments (for comparative evaluation)
author Chris Cannam
date Wed, 04 Jun 2014 12:00:55 +0100
parents 59e3cca75b8d
children ce8118644f16 5bde003a43a9
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@161 37 "Cello", "cello",
Chris@161 38 "Horn", "horn",
Chris@161 39 "Flute", "flute",
Chris@161 40 "Oboe", "oboe",
Chris@161 41 "Clarinet", "clarinet",
Chris@161 42 "Tenor Sax", "tenorsax",
Chris@161 43 "Bassoon", "bassoon",
Chris@161 44 };
Chris@161 45
Chris@176 46 static bool
Chris@176 47 isString(int i)
Chris@176 48 {
Chris@176 49 string tname(simpleInstruments[i+1]);
Chris@176 50 return tname == "violin"
Chris@176 51 || tname == "cello"
Chris@176 52 ;
Chris@176 53 }
Chris@176 54
Chris@176 55 static bool
Chris@176 56 isWind(int i)
Chris@176 57 {
Chris@176 58 string tname(simpleInstruments[i+1]);
Chris@176 59 return tname == "horn"
Chris@176 60 || tname == "flute"
Chris@176 61 || tname == "oboe"
Chris@176 62 || tname == "clarinet"
Chris@176 63 || tname == "tenorsax"
Chris@176 64 || tname == "bassoon"
Chris@176 65 ;
Chris@176 66 }
Chris@176 67
Chris@161 68 static InstrumentPack::Templates
Chris@161 69 templatesFor(string name)
Chris@161 70 {
Chris@161 71 for (int i = 0; i < SILVET_TEMPLATE_COUNT; ++i) {
Chris@161 72
Chris@161 73 if (string(silvet_templates[i].name) == name) {
Chris@161 74
Chris@161 75 silvet_template_t *t = &silvet_templates[i];
Chris@161 76
Chris@161 77 InstrumentPack::Templates rt;
Chris@161 78 rt.lowestNote = t->lowest;
Chris@161 79 rt.highestNote = t->highest;
Chris@161 80 rt.data = vector<vector<float> >
Chris@161 81 (SILVET_TEMPLATE_NOTE_COUNT,
Chris@161 82 vector<float>(SILVET_TEMPLATE_SIZE, 0.f));
Chris@161 83
Chris@161 84 for (int j = 0; j < SILVET_TEMPLATE_NOTE_COUNT; ++j) {
Chris@161 85 for (int k = 0; k < SILVET_TEMPLATE_SIZE; ++k) {
Chris@161 86 rt.data[j][k] = t->data[j][k];
Chris@161 87 }
Chris@161 88 }
Chris@161 89
Chris@161 90 return rt;
Chris@161 91 }
Chris@161 92 }
Chris@161 93
Chris@161 94 return InstrumentPack::Templates();
Chris@161 95 }
Chris@161 96
Chris@161 97 static bool
Chris@161 98 isOK(InstrumentPack &d)
Chris@161 99 {
Chris@161 100 if (d.name == "") {
Chris@161 101 cerr << "ERROR: Silvet::InstrumentPack: Empty name in instrument definition" << endl;
Chris@161 102 return false;
Chris@161 103 }
Chris@161 104 if (d.templates.empty()) {
Chris@161 105 cerr << "ERROR: Silvet::InstrumentPack: Instrument definition \"" << d.name << "\" contains no templates!" << endl;
Chris@161 106 return false;
Chris@161 107 }
Chris@161 108 for (int i = 0; i < int(d.templates.size()); ++i) {
Chris@161 109 if (d.templates[i].data.empty()) {
Chris@161 110 cerr << "ERROR: Silvet::InstrumentPack: Instrument definition \"" << d.name << "\" contains one or more empty templates!" << endl;
Chris@161 111 return false;
Chris@161 112 }
Chris@161 113 }
Chris@161 114 return true;
Chris@161 115 }
Chris@161 116
Chris@161 117 vector<InstrumentPack>
Chris@161 118 InstrumentPack::listInstrumentPacks()
Chris@161 119 {
Chris@161 120 vector<InstrumentPack> ii;
Chris@161 121
Chris@161 122 vector<Templates> allTemplates;
Chris@161 123 //!!! is piano-maps-SptkBGCl the same as one of piano1, piano2, piano3?
Chris@161 124 allTemplates.push_back(templatesFor("piano1"));
Chris@161 125
Chris@161 126 vector<Templates> pianoTemplates;
Chris@161 127 pianoTemplates.push_back(templatesFor("piano1"));
Chris@161 128 pianoTemplates.push_back(templatesFor("piano2"));
Chris@161 129 pianoTemplates.push_back(templatesFor("piano3"));
Chris@161 130 InstrumentPack piano(silvet_templates_lowest_note,
Chris@161 131 silvet_templates_highest_note,
Chris@161 132 "Piano",
Chris@161 133 pianoTemplates);
Chris@200 134 // piano.maxPolyphony = 8;
Chris@200 135 // piano.levelThreshold = 3;
Chris@200 136 piano.maxPolyphony = 5;
Chris@200 137 piano.levelThreshold = 6;
Chris@161 138 if (isOK(piano)) {
Chris@161 139 ii.push_back(piano);
Chris@161 140 }
Chris@161 141
Chris@176 142 vector<Templates> stringTemplates;
Chris@176 143 vector<Templates> windTemplates;
Chris@176 144
Chris@161 145 for (int i = 0;
Chris@161 146 i < int(sizeof(simpleInstruments)/sizeof(simpleInstruments[0]));
Chris@161 147 i += 2) {
Chris@161 148 vector<Templates> tt;
Chris@161 149 Templates t = templatesFor(simpleInstruments[i+1]);
Chris@161 150 tt.push_back(t);
Chris@161 151 allTemplates.push_back(t);
Chris@161 152 InstrumentPack instr(t.lowestNote,
Chris@161 153 t.highestNote,
Chris@161 154 simpleInstruments[i],
Chris@161 155 tt);
Chris@200 156 // instr.pitchSparsity = 1.5;
Chris@200 157 instr.maxPolyphony = 5;
Chris@200 158 instr.levelThreshold = 6;
Chris@183 159 if (isString(i)) {
Chris@200 160 // instr.maxPolyphony = 2;
Chris@200 161 // instr.levelThreshold = 3;
Chris@183 162 stringTemplates.push_back(t);
Chris@183 163 }
Chris@183 164 if (isWind(i)) {
Chris@200 165 // instr.maxPolyphony = 1;
Chris@200 166 // instr.levelThreshold = 5;
Chris@183 167 windTemplates.push_back(t);
Chris@183 168 }
Chris@161 169 if (isOK(instr)) {
Chris@161 170 ii.push_back(instr);
Chris@161 171 }
Chris@161 172 }
Chris@161 173
Chris@161 174 InstrumentPack all(silvet_templates_lowest_note,
Chris@161 175 silvet_templates_highest_note,
Chris@161 176 "Multiple or unknown instruments",
Chris@161 177 allTemplates);
Chris@183 178 all.maxPolyphony = 5;
Chris@183 179 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 180 if (isOK(all)) {
Chris@161 181 ii.insert(ii.begin(), all);
Chris@161 182 }
Chris@161 183
Chris@176 184 InstrumentPack strings(silvet_templates_lowest_note, // cello
Chris@176 185 silvet_templates_highest_note, // violin
Chris@176 186 "String ensemble",
Chris@176 187 stringTemplates);
Chris@183 188 strings.maxPolyphony = 5;
Chris@183 189 strings.levelThreshold = 3;
Chris@176 190 if (isOK(strings)) {
Chris@176 191 ii.push_back(strings);
Chris@176 192 }
Chris@176 193
Chris@176 194 InstrumentPack winds(silvet_templates_lowest_note, // basson
Chris@176 195 silvet_templates_highest_note, // flute
Chris@176 196 "Wind ensemble",
Chris@176 197 windTemplates);
Chris@183 198 winds.maxPolyphony = 5;
Chris@183 199 winds.levelThreshold = 5;
Chris@176 200 if (isOK(winds)) {
Chris@176 201 ii.push_back(winds);
Chris@176 202 }
Chris@176 203
Chris@161 204 return ii;
Chris@161 205 }
Chris@161 206