Chris@298: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@298: Chris@298: /* Chris@298: Silvet Chris@298: Chris@298: A Vamp plugin for note transcription. Chris@298: Centre for Digital Music, Queen Mary University of London. Chris@298: Chris@298: This program is free software; you can redistribute it and/or Chris@298: modify it under the terms of the GNU General Public License as Chris@298: published by the Free Software Foundation; either version 2 of the Chris@298: License, or (at your option) any later version. See the file Chris@298: COPYING included with this distribution for more information. Chris@298: */ Chris@298: Chris@298: #include "LiveInstruments.h" Chris@298: Chris@298: #include "data/include/templates.h" Chris@298: Chris@301: #include Chris@301: Chris@298: using namespace std; Chris@298: Chris@298: InstrumentPack Chris@298: LiveAdapter::adapt(const InstrumentPack &original) Chris@298: { Chris@298: vector templates; Chris@298: Chris@303: // cerr << "LiveAdapter: reduced template height is " << SILVET_TEMPLATE_HEIGHT/5 << endl; Chris@298: Chris@322: bool merge = false; Chris@322: // The live template for piano has only one piano in it, so as Chris@322: // to process faster. We make it by averaging the originals Chris@322: if (original.name == "Piano") { Chris@322: merge = true; Chris@322: } Chris@298: Chris@322: InstrumentPack::Templates t; Chris@322: bool first = true; Chris@322: Chris@322: for (const auto &origt: original.templates) { Chris@322: Chris@322: t.lowestNote = origt.lowestNote; Chris@322: t.highestNote = origt.highestNote; Chris@322: t.data.resize(origt.data.size()); Chris@322: Chris@322: for (int j = 0; j < int(origt.data.size()); ++j) { Chris@301: Chris@298: t.data[j].resize(SILVET_TEMPLATE_HEIGHT/5); Chris@301: Chris@298: for (int k = 0; k < SILVET_TEMPLATE_HEIGHT/5; ++k) { Chris@301: Chris@322: if (!merge || first) { Chris@322: t.data[j][k] = 0.f; Chris@322: } Chris@301: Chris@301: for (int m = 0; m < 5; ++m) { Chris@322: t.data[j][k] += origt.data[j][k * 5 + m + 2]; Chris@301: } Chris@298: } Chris@298: } Chris@299: Chris@322: if (!merge) { Chris@322: templates.push_back(t); Chris@322: t = InstrumentPack::Templates(); Chris@322: } Chris@315: Chris@322: first = false; Chris@322: } Chris@322: Chris@322: if (merge) { Chris@322: templates.push_back(t); Chris@322: } Chris@322: Chris@322: // re-normalise Chris@322: for (auto &t: templates) { Chris@322: for (auto &d: t.data) { Chris@322: float sum = 0.f; Chris@322: for (auto v: d) sum += v; Chris@346: if (sum > 0.f) { Chris@346: for (auto &v: d) v /= sum; Chris@346: } Chris@315: } Chris@298: } Chris@298: Chris@298: InstrumentPack live(original.lowestNote, Chris@298: original.highestNote, Chris@298: original.name, Chris@298: templates); Chris@298: Chris@298: live.templateHeight = SILVET_TEMPLATE_HEIGHT/5; Chris@298: live.templateMaxShift = 0; Chris@298: live.templateSize = live.templateHeight; Chris@298: Chris@298: live.maxPolyphony = original.maxPolyphony; Chris@298: live.pitchSparsity = original.pitchSparsity; Chris@298: live.sourceSparsity = original.sourceSparsity; Chris@325: live.levelThreshold = original.levelThreshold / 15; Chris@298: Chris@298: return live; Chris@298: } Chris@298: Chris@298: vector Chris@298: LiveAdapter::adaptAll(const vector &v) Chris@298: { Chris@298: vector out; Chris@298: for (int i = 0; i < (int)v.size(); ++i) { Chris@298: InstrumentPack p(LiveAdapter::adapt(v[i])); Chris@298: out.push_back(p); Chris@298: } Chris@298: return out; Chris@298: }