annotate src/Instruments.cpp @ 281:405a2ad601f4

drand48 isn't so portable and we don't really need high-quality randomness, use rand instead
author Chris Cannam
date Wed, 06 Aug 2014 16:44:44 +0100
parents 00d76494a722
children ebe5e0942bb8
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@266 136 piano.maxPolyphony = 6;
Chris@200 137 piano.levelThreshold = 6;
Chris@213 138 piano.pitchSparsity = 1.0;
Chris@213 139 piano.sourceSparsity = 1.0;
Chris@161 140 if (isOK(piano)) {
Chris@161 141 ii.push_back(piano);
Chris@161 142 }
Chris@161 143
Chris@176 144 vector<Templates> stringTemplates;
Chris@176 145 vector<Templates> windTemplates;
Chris@176 146
Chris@161 147 for (int i = 0;
Chris@161 148 i < int(sizeof(simpleInstruments)/sizeof(simpleInstruments[0]));
Chris@161 149 i += 2) {
Chris@213 150
Chris@161 151 vector<Templates> tt;
Chris@161 152 Templates t = templatesFor(simpleInstruments[i+1]);
Chris@161 153 tt.push_back(t);
Chris@161 154 allTemplates.push_back(t);
Chris@161 155 InstrumentPack instr(t.lowestNote,
Chris@161 156 t.highestNote,
Chris@161 157 simpleInstruments[i],
Chris@161 158 tt);
Chris@266 159
Chris@200 160 instr.maxPolyphony = 5;
Chris@200 161 instr.levelThreshold = 6;
Chris@266 162
Chris@220 163 if (isBowedString(i)) {
Chris@266 164 instr.maxPolyphony = 2;
Chris@268 165 instr.levelThreshold = 5;
Chris@183 166 stringTemplates.push_back(t);
Chris@183 167 }
Chris@183 168 if (isWind(i)) {
Chris@266 169 instr.maxPolyphony = 2;
Chris@183 170 windTemplates.push_back(t);
Chris@183 171 }
Chris@161 172 if (isOK(instr)) {
Chris@161 173 ii.push_back(instr);
Chris@161 174 }
Chris@161 175 }
Chris@161 176
Chris@161 177 InstrumentPack all(silvet_templates_lowest_note,
Chris@161 178 silvet_templates_highest_note,
Chris@161 179 "Multiple or unknown instruments",
Chris@161 180 allTemplates);
Chris@183 181 all.maxPolyphony = 5;
Chris@268 182 all.levelThreshold = 6;
Chris@161 183 if (isOK(all)) {
Chris@161 184 ii.insert(ii.begin(), all);
Chris@161 185 }
Chris@161 186
Chris@176 187 InstrumentPack strings(silvet_templates_lowest_note, // cello
Chris@176 188 silvet_templates_highest_note, // violin
Chris@220 189 "String quartet",
Chris@176 190 stringTemplates);
Chris@183 191 strings.maxPolyphony = 5;
Chris@268 192 strings.levelThreshold = 5;
Chris@176 193 if (isOK(strings)) {
Chris@176 194 ii.push_back(strings);
Chris@176 195 }
Chris@176 196
Chris@176 197 InstrumentPack winds(silvet_templates_lowest_note, // basson
Chris@176 198 silvet_templates_highest_note, // flute
Chris@176 199 "Wind ensemble",
Chris@176 200 windTemplates);
Chris@183 201 winds.maxPolyphony = 5;
Chris@183 202 winds.levelThreshold = 5;
Chris@176 203 if (isOK(winds)) {
Chris@176 204 ii.push_back(winds);
Chris@176 205 }
Chris@176 206
Chris@161 207 return ii;
Chris@161 208 }
Chris@161 209