Chris@161: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@161: Chris@161: /* Chris@161: Silvet Chris@161: Chris@161: A Vamp plugin for note transcription. Chris@161: Centre for Digital Music, Queen Mary University of London. Chris@161: Chris@161: This program is free software; you can redistribute it and/or Chris@161: modify it under the terms of the GNU General Public License as Chris@161: published by the Free Software Foundation; either version 2 of the Chris@161: License, or (at your option) any later version. See the file Chris@161: COPYING included with this distribution for more information. Chris@161: */ Chris@161: Chris@161: #include "Instruments.h" Chris@161: Chris@161: #include "data/include/templates.h" Chris@161: Chris@161: #include Chris@161: Chris@161: using std::string; Chris@161: using std::vector; Chris@161: using std::cerr; Chris@161: using std::endl; Chris@161: Chris@298: InstrumentPack::InstrumentPack(int lowest, int highest, Chris@298: std::string n, std::vector tt) : Chris@298: templateNoteCount(SILVET_TEMPLATE_NOTE_COUNT), Chris@298: templateHeight(SILVET_TEMPLATE_HEIGHT), Chris@298: templateMaxShift(SILVET_TEMPLATE_MAX_SHIFT), Chris@298: templateSize(SILVET_TEMPLATE_SIZE), Chris@298: lowestNote(lowest), Chris@298: highestNote(highest), Chris@298: maxPolyphony(5), Chris@298: pitchSparsity(1.1), Chris@298: sourceSparsity(1.2), Chris@298: levelThreshold(5), Chris@298: name(n), Chris@298: templates(tt) Chris@298: { Chris@298: } Chris@298: Chris@161: const char *simpleInstruments[] = { Chris@176: // Each instrument has two consecutive slots, one for the pack Chris@176: // name and one for the template to look up Chris@161: "Guitar", "guitar", Chris@161: "Violin", "violin", Chris@220: "Viola", "viola", Chris@161: "Cello", "cello", Chris@161: "Horn", "horn", Chris@161: "Flute", "flute", Chris@161: "Oboe", "oboe", Chris@161: "Clarinet", "clarinet", Chris@161: "Tenor Sax", "tenorsax", Chris@161: "Bassoon", "bassoon", Chris@161: }; Chris@161: Chris@176: static bool Chris@220: isBowedString(int i) Chris@176: { Chris@176: string tname(simpleInstruments[i+1]); Chris@176: return tname == "violin" Chris@220: || tname == "viola" Chris@176: || tname == "cello" Chris@176: ; Chris@176: } Chris@176: Chris@176: static bool Chris@176: isWind(int i) Chris@176: { Chris@176: string tname(simpleInstruments[i+1]); Chris@176: return tname == "horn" Chris@176: || tname == "flute" Chris@176: || tname == "oboe" Chris@176: || tname == "clarinet" Chris@176: || tname == "tenorsax" Chris@176: || tname == "bassoon" Chris@176: ; Chris@176: } Chris@176: Chris@161: static InstrumentPack::Templates Chris@161: templatesFor(string name) Chris@161: { Chris@161: for (int i = 0; i < SILVET_TEMPLATE_COUNT; ++i) { Chris@161: Chris@161: if (string(silvet_templates[i].name) == name) { Chris@161: Chris@161: silvet_template_t *t = &silvet_templates[i]; Chris@161: Chris@161: InstrumentPack::Templates rt; Chris@161: rt.lowestNote = t->lowest; Chris@161: rt.highestNote = t->highest; Chris@161: rt.data = vector > Chris@161: (SILVET_TEMPLATE_NOTE_COUNT, Chris@161: vector(SILVET_TEMPLATE_SIZE, 0.f)); Chris@161: Chris@161: for (int j = 0; j < SILVET_TEMPLATE_NOTE_COUNT; ++j) { Chris@161: for (int k = 0; k < SILVET_TEMPLATE_SIZE; ++k) { Chris@161: rt.data[j][k] = t->data[j][k]; Chris@161: } Chris@161: } Chris@161: Chris@161: return rt; Chris@161: } Chris@161: } Chris@161: Chris@161: return InstrumentPack::Templates(); Chris@161: } Chris@161: Chris@161: static bool Chris@161: isOK(InstrumentPack &d) Chris@161: { Chris@161: if (d.name == "") { Chris@161: cerr << "ERROR: Silvet::InstrumentPack: Empty name in instrument definition" << endl; Chris@161: return false; Chris@161: } Chris@161: if (d.templates.empty()) { Chris@161: cerr << "ERROR: Silvet::InstrumentPack: Instrument definition \"" << d.name << "\" contains no templates!" << endl; Chris@161: return false; Chris@161: } Chris@161: for (int i = 0; i < int(d.templates.size()); ++i) { Chris@161: if (d.templates[i].data.empty()) { Chris@161: cerr << "ERROR: Silvet::InstrumentPack: Instrument definition \"" << d.name << "\" contains one or more empty templates!" << endl; Chris@161: return false; Chris@161: } Chris@161: } Chris@161: return true; Chris@161: } Chris@161: Chris@161: vector Chris@161: InstrumentPack::listInstrumentPacks() Chris@161: { Chris@161: vector ii; Chris@161: Chris@161: vector allTemplates; Chris@161: allTemplates.push_back(templatesFor("piano1")); Chris@161: Chris@161: vector pianoTemplates; Chris@161: pianoTemplates.push_back(templatesFor("piano1")); Chris@161: pianoTemplates.push_back(templatesFor("piano2")); Chris@161: pianoTemplates.push_back(templatesFor("piano3")); Chris@220: pianoTemplates.push_back(templatesFor("pianorwc")); Chris@161: InstrumentPack piano(silvet_templates_lowest_note, Chris@161: silvet_templates_highest_note, Chris@161: "Piano", Chris@161: pianoTemplates); Chris@266: piano.maxPolyphony = 6; Chris@339: piano.levelThreshold = 5; Chris@213: piano.pitchSparsity = 1.0; Chris@213: piano.sourceSparsity = 1.0; Chris@161: if (isOK(piano)) { Chris@161: ii.push_back(piano); Chris@161: } Chris@161: Chris@176: vector stringTemplates; Chris@176: vector windTemplates; Chris@176: Chris@161: for (int i = 0; Chris@161: i < int(sizeof(simpleInstruments)/sizeof(simpleInstruments[0])); Chris@161: i += 2) { Chris@213: Chris@161: vector tt; Chris@161: Templates t = templatesFor(simpleInstruments[i+1]); Chris@161: tt.push_back(t); Chris@161: allTemplates.push_back(t); Chris@161: InstrumentPack instr(t.lowestNote, Chris@161: t.highestNote, Chris@161: simpleInstruments[i], Chris@161: tt); Chris@266: Chris@200: instr.maxPolyphony = 5; Chris@200: instr.levelThreshold = 6; Chris@266: Chris@220: if (isBowedString(i)) { Chris@266: instr.maxPolyphony = 2; Chris@268: instr.levelThreshold = 5; Chris@183: stringTemplates.push_back(t); Chris@183: } Chris@183: if (isWind(i)) { Chris@266: instr.maxPolyphony = 2; Chris@183: windTemplates.push_back(t); Chris@183: } Chris@161: if (isOK(instr)) { Chris@161: ii.push_back(instr); Chris@161: } Chris@161: } Chris@161: Chris@161: InstrumentPack all(silvet_templates_lowest_note, Chris@161: silvet_templates_highest_note, Chris@161: "Multiple or unknown instruments", Chris@161: allTemplates); Chris@183: all.maxPolyphony = 5; Chris@268: all.levelThreshold = 6; Chris@161: if (isOK(all)) { Chris@161: ii.insert(ii.begin(), all); Chris@161: } Chris@161: Chris@176: InstrumentPack strings(silvet_templates_lowest_note, // cello Chris@176: silvet_templates_highest_note, // violin Chris@220: "String quartet", Chris@176: stringTemplates); Chris@340: strings.maxPolyphony = 6; Chris@340: strings.levelThreshold = 3; Chris@176: if (isOK(strings)) { Chris@176: ii.push_back(strings); Chris@176: } Chris@176: Chris@176: InstrumentPack winds(silvet_templates_lowest_note, // basson Chris@176: silvet_templates_highest_note, // flute Chris@176: "Wind ensemble", Chris@176: windTemplates); Chris@183: winds.maxPolyphony = 5; Chris@183: winds.levelThreshold = 5; Chris@176: if (isOK(winds)) { Chris@176: ii.push_back(winds); Chris@176: } Chris@176: Chris@161: return ii; Chris@161: } Chris@161: