summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2018-06-17 15:26:07 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2018-08-12 11:11:44 +0200
commitbd0e48a876f25751ae7e0d025178b19d773ca00e (patch)
treea503de41fbae079d2ea8084d2d4d716482413896
parent8dd1ea54a2d2198004c82fe75b45714917b440a1 (diff)
Finished DOMLoader and fixed the broken unit-tests.
-rw-r--r--src/DGDOM.h3
-rw-r--r--src/dgxmlparser.cc10
-rw-r--r--src/domloader.cc143
-rw-r--r--src/domloader.h6
-rw-r--r--src/instrument.cc2
-rw-r--r--test/dgxmlparsertest.cc7
-rw-r--r--test/domloadertest.cc40
-rw-r--r--test/drumkit_creator.cc8
8 files changed, 184 insertions, 35 deletions
diff --git a/src/DGDOM.h b/src/DGDOM.h
index 308a880..df03515 100644
--- a/src/DGDOM.h
+++ b/src/DGDOM.h
@@ -56,6 +56,8 @@ struct InstrumentChannelDOM
struct InstrumentDOM
{
std::string name;
+ std::string version;
+ std::string description;
std::vector<SampleDOM> samples;
std::vector<InstrumentChannelDOM> instrument_channels;
};
@@ -86,6 +88,7 @@ struct InstrumentRefDOM
struct DrumkitDOM
{
std::string name;
+ std::string version;
std::string description;
double samplerate;
diff --git a/src/dgxmlparser.cc b/src/dgxmlparser.cc
index cc76b3e..3fdedc2 100644
--- a/src/dgxmlparser.cc
+++ b/src/dgxmlparser.cc
@@ -114,9 +114,11 @@ bool parseDrumkitFile(const std::string& filename, DrumkitDOM& dom)
//TODO: handle xml version
pugi::xml_node drumkit = doc.child("drumkit");
- res &= attrcpy(dom.description, drumkit, "description");
res &= attrcpy(dom.name, drumkit, "name");
- res &= attrcpy(dom.samplerate, drumkit, "samplerate");
+ res &= attrcpy(dom.version, drumkit, "version");
+ res &= attrcpy(dom.description, drumkit, "description");
+ dom.samplerate = 44100.0;
+ res &= attrcpy(dom.samplerate, drumkit, "samplerate", true);
pugi::xml_node channels = doc.child("drumkit").child("channels");
for(pugi::xml_node channel: channels.children("channel"))
@@ -158,6 +160,8 @@ bool parseInstrumentFile(const std::string& filename, InstrumentDOM& dom)
pugi::xml_node instrument = doc.child("instrument");
res &= attrcpy(dom.name, instrument, "name");
+ res &= attrcpy(dom.version, instrument, "version");
+ res &= attrcpy(dom.description, instrument, "description", true);
pugi::xml_node channels = instrument.child("channels");
for(pugi::xml_node channel : channels.children("channel"))
@@ -168,7 +172,7 @@ bool parseInstrumentFile(const std::string& filename, InstrumentDOM& dom)
res &= attrcpy(dom.instrument_channels.back().main, channel, "main", true);
}
- pugi::xml_node samples = doc.child("instrument").child("samples");
+ pugi::xml_node samples = instrument.child("samples");
for(pugi::xml_node sample: samples.children("sample"))
{
dom.samples.emplace_back();
diff --git a/src/domloader.cc b/src/domloader.cc
index aa7d1e2..f72f0eb 100644
--- a/src/domloader.cc
+++ b/src/domloader.cc
@@ -26,11 +26,23 @@
*/
#include "domloader.h"
+#include <unordered_map>
+
+#include <hugin.hpp>
+
#include "DGDOM.h"
#include "drumkit.h"
+#include "path.h"
+#include "channel.h"
#include "cpp11fix.h"
+struct channel_attribute_t
+{
+ std::string cname;
+ main_state_t main_state;
+};
+
DOMLoader::DOMLoader(Settings& settings, Random& random)
: settings(settings)
, random(random)
@@ -41,7 +53,10 @@ bool DOMLoader::loadDom(const DrumkitDOM& dom,
const std::vector<InstrumentDOM>& instrumentdoms,
DrumKit& drumkit)
{
+ settings.has_bleed_control.store(false);
+
drumkit._name = dom.name;
+ drumkit._version = dom.version;
drumkit._description = dom.description;
drumkit._samplerate = dom.samplerate;
@@ -54,15 +69,131 @@ bool DOMLoader::loadDom(const DrumkitDOM& dom,
for(const auto& instrumentref : dom.instruments)
{
- auto ptr = std::make_unique<Instrument>(settings, random);
- ptr->setGroup(instrumentref.group);
+ bool found{found};
+
+ std::unordered_map<std::string, channel_attribute_t> channelmap;
+ for(const auto& map : instrumentref.channel_map)
+ {
+ channel_attribute_t cattr{map.out, map.main};
+ channelmap[map.in] = cattr;
+ }
+
+ for(const auto& instrumentdom : instrumentdoms)
+ {
+ if(instrumentdom.name != instrumentref.name)
+ {
+ continue;
+ }
+
+ auto instrument = std::make_unique<Instrument>(settings, random);
+ instrument->setGroup(instrumentref.group);
+ instrument->_name = instrumentdom.name;
+ instrument->version = instrumentdom.version;
+ instrument->_description = instrumentdom.description;
+
+ auto path = getPath(instrumentref.file);
+ for(const auto& sampledom : instrumentdom.samples)
+ {
+ auto sample = new Sample(sampledom.name, sampledom.power);
+ for(const auto& audiofiledom : sampledom.audiofiles)
+ {
+ InstrumentChannel *instrument_channel =
+ DOMLoader::addOrGetChannel(*instrument,
+ audiofiledom.instrument_channel);
+
+ auto audio_file =
+ std::make_unique<AudioFile>(path + "/" + audiofiledom.file,
+ audiofiledom.filechannel - 1,
+ instrument_channel);
+
+ sample->addAudioFile(instrument_channel,
+ audio_file.get());
+
+ // Transfer audio_file ownership to the instrument.
+ instrument->audiofiles.push_back(std::move(audio_file));
+ }
+ instrument->samplelist.push_back(sample);
+ }
+
+ main_state_t default_main_state = main_state_t::unset;
+ for(const auto& channel : channelmap)
+ {
+ if(channel.second.main_state != main_state_t::unset)
+ {
+ default_main_state = main_state_t::is_not_main;
+ }
+ }
- //InstrumentParser parser(*ptr, settings);
- //parser.parseFile(path + "/" + instr_file);
+ // Assign kit channel numbers to instruments channels and reset
+ // main_state attribute as needed.
+ for(auto& instrument_channel: instrument->instrument_channels)
+ {
+ channel_attribute_t cattr{instrument_channel.name, main_state_t::unset};
+ if(channelmap.find(instrument_channel.name) != channelmap.end())
+ {
+ cattr = channelmap[instrument_channel.name];
+ }
- // Transfer ownership to the DrumKit object.
- drumkit.instruments.emplace_back(std::move(ptr));
+ if(cattr.main_state == main_state_t::unset)
+ {
+ cattr.main_state = default_main_state;
+ }
+
+ if(cattr.main_state != main_state_t::unset)
+ {
+ instrument_channel.main = cattr.main_state;
+ }
+
+ for(auto cnt = 0u; cnt < drumkit.channels.size(); ++cnt)
+ {
+ if(drumkit.channels[cnt].name == cattr.cname)
+ {
+ instrument_channel.num = drumkit.channels[cnt].num;
+ instrument_channel.name = drumkit.channels[cnt].name;
+ if(instrument_channel.main == main_state_t::is_main)
+ {
+ settings.has_bleed_control.store(true);
+ }
+ }
+ }
+
+ if(instrument_channel.num == NO_CHANNEL)
+ {
+ ERR(kitparser, "Missing channel '%s' in instrument '%s'\n",
+ instrument_channel.name.c_str(), instrument->getName().c_str());
+ }
+ }
+
+ // Transfer ownership to the DrumKit object.
+ drumkit.instruments.emplace_back(std::move(instrument));
+
+ found = true;
+ }
+
+ if(!found)
+ {
+ ERR(domloader, "No instrument with name '%s'", instrumentref.name.data());
+ return false;
+ }
}
return true;
}
+
+InstrumentChannel* DOMLoader::addOrGetChannel(Instrument& instrument,
+ const std::string& name)
+{
+ for(auto& channel : instrument.instrument_channels)
+ {
+ if(channel.name == name)
+ {
+ return &channel;
+ }
+ }
+
+ instrument.instrument_channels.emplace_back(name);
+ InstrumentChannel& channel = instrument.instrument_channels.back();
+ channel.main = main_state_t::unset;
+
+ return &channel;
+}
diff --git a/src/domloader.h b/src/domloader.h
index 29288c5..d627ce6 100644
--- a/src/domloader.h
+++ b/src/domloader.h
@@ -27,12 +27,15 @@
#pragma once
#include <vector>
+#include <string>
class DrumkitDOM;
class InstrumentDOM;
class DrumKit;
class Settings;
class Random;
+class InstrumentChannel;
+class Instrument;
class DOMLoader
{
@@ -44,6 +47,9 @@ public:
DrumKit& drumkit);
private:
+ static InstrumentChannel* addOrGetChannel(Instrument& instrument,
+ const std::string& name);
+
Settings& settings;
Random& random;
};
diff --git a/src/instrument.cc b/src/instrument.cc
index 48b6505..c1cd4aa 100644
--- a/src/instrument.cc
+++ b/src/instrument.cc
@@ -120,6 +120,8 @@ void Instrument::setGroup(const std::string& g)
std::size_t Instrument::getNumberOfFiles() const
{
+ DEBUG(instrument, "audiofiles.size() %d", (int)audiofiles.size());
+
// Note: Each AudioFile instance contains just a single channel even for
// multi-channel files.
return audiofiles.size();
diff --git a/test/dgxmlparsertest.cc b/test/dgxmlparsertest.cc
index 16bcbd2..30bcfa7 100644
--- a/test/dgxmlparsertest.cc
+++ b/test/dgxmlparsertest.cc
@@ -43,7 +43,7 @@ public:
{
ScopedFile scoped_file(
"<?xml version='1.0' encoding='UTF-8'?>\n" \
- "<instrument version=\"2.0\" name=\"Snare\">\n" \
+ "<instrument version=\"2.0\" name=\"Snare\" description=\"A nice snare\">\n" \
" <channels>\n" \
" <channel name=\"AmbLeft\" main=\"true\"/>\n" \
" <channel name=\"AmbRight\" main=\"false\"/>\n" \
@@ -70,6 +70,8 @@ public:
DGUNIT_ASSERT(parseInstrumentFile(scoped_file.filename(), dom));
DGUNIT_ASSERT_EQUAL(std::string("Snare"), dom.name);
+ DGUNIT_ASSERT_EQUAL(std::string("2.0"), dom.version);
+ DGUNIT_ASSERT_EQUAL(std::string("A nice snare"), dom.description);
DGUNIT_ASSERT_EQUAL(std::size_t(2), dom.samples.size());
{
@@ -130,7 +132,7 @@ public:
{
ScopedFile scoped_file(
"<?xml version='1.0' encoding='UTF-8'?>\n" \
- "<drumkit name=\"CrocellKit\" description=\"my description\" samplerate=\"48000\" version=\"2.0.0\">\n" \
+ "<drumkit name=\"CrocellKit\" description=\"my description\" samplerate=\"48000\" version=\"2.0\">\n" \
" <channels>\n" \
" <channel name=\"AmbLeft\"/>\n" \
" <channel name=\"AmbRight\"/>\n" \
@@ -158,6 +160,7 @@ public:
DGUNIT_ASSERT(parseDrumkitFile(scoped_file.filename(), dom));
DGUNIT_ASSERT_EQUAL(std::string("CrocellKit"), dom.name);
+ DGUNIT_ASSERT_EQUAL(std::string("2.0"), dom.version);
DGUNIT_ASSERT_EQUAL(std::string("my description"), dom.description);
DGUNIT_ASSERT_EQUAL(48000.0, dom.samplerate);
DGUNIT_ASSERT_EQUAL(std::size_t(2), dom.instruments.size());
diff --git a/test/domloadertest.cc b/test/domloadertest.cc
index 2c9c5eb..69b9821 100644
--- a/test/domloadertest.cc
+++ b/test/domloadertest.cc
@@ -52,7 +52,7 @@ public:
{
ScopedFile scoped_instrument_file1(
"<?xml version='1.0' encoding='UTF-8'?>\n" \
- "<instrument version=\"2.0\" name=\"Snare\">\n" \
+ "<instrument version=\"2.0\" name=\"Snare1\">\n" \
" <samples>\n" \
" <sample name=\"Snare-1\" power=\"0.00985718\">\n" \
" <audiofile channel=\"AmbLeft\" file=\"1-Snare.wav\" filechannel=\"1\"/>\n" \
@@ -71,7 +71,7 @@ public:
ScopedFile scoped_instrument_file2(
"<?xml version='1.0' encoding='UTF-8'?>\n" \
- "<instrument version=\"2.0\" name=\"Snare\">\n" \
+ "<instrument version=\"2.0\" name=\"Snare2\">\n" \
" <samples>\n" \
" <sample name=\"Snare-1\" power=\"0.00985718\">\n" \
" <audiofile channel=\"AmbLeft2\" file=\"1-Snare.wav\" filechannel=\"1\"/>\n" \
@@ -152,7 +152,7 @@ public:
{
auto& instrument = *drumkit.instruments[0];
DGUNIT_ASSERT_EQUAL(std::string(""), instrument._group);
- DGUNIT_ASSERT_EQUAL(std::string("Snare"), instrument._name);
+ DGUNIT_ASSERT_EQUAL(std::string("Snare1"), instrument._name);
DGUNIT_ASSERT_EQUAL(std::string(""), instrument._description);
DGUNIT_ASSERT(VersionStr("2.0.0") == instrument.version);
@@ -172,19 +172,19 @@ public:
// NOTE: Channel numbers are zero based - they are 1 based in the xml
case 0:
DGUNIT_ASSERT_EQUAL(std::string("AmbLeft"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 1:
DGUNIT_ASSERT_EQUAL(std::string("AmbRight"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 11:
DGUNIT_ASSERT_EQUAL(std::string("SnareBottom"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 12:
DGUNIT_ASSERT_EQUAL(std::string("SnareTop"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
default:
DGUNIT_ASSERT(false);
@@ -206,19 +206,19 @@ public:
// NOTE: Channel numbers are zero based - they are 1 based in the xml
case 0:
DGUNIT_ASSERT_EQUAL(std::string("AmbLeft"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 1:
DGUNIT_ASSERT_EQUAL(std::string("AmbRight"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 11:
DGUNIT_ASSERT_EQUAL(std::string("SnareBottom"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 12:
DGUNIT_ASSERT_EQUAL(std::string("SnareTop"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
default:
DGUNIT_ASSERT(false);
@@ -235,7 +235,7 @@ public:
{
auto& instrument = *drumkit.instruments[1];
DGUNIT_ASSERT_EQUAL(std::string(""), instrument._group);
- DGUNIT_ASSERT_EQUAL(std::string("Snare"), instrument._name);
+ DGUNIT_ASSERT_EQUAL(std::string("Snare2"), instrument._name);
DGUNIT_ASSERT_EQUAL(std::string(""), instrument._description);
DGUNIT_ASSERT(VersionStr("2.0.0") == instrument.version);
@@ -255,19 +255,19 @@ public:
// NOTE: Channel numbers are zero based - they are 1 based in the xml
case 0:
DGUNIT_ASSERT_EQUAL(std::string("AmbLeft"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 1:
DGUNIT_ASSERT_EQUAL(std::string("AmbRight"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 11:
DGUNIT_ASSERT_EQUAL(std::string("SnareBottom"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 12:
DGUNIT_ASSERT_EQUAL(std::string("SnareTop"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
default:
DGUNIT_ASSERT(false);
@@ -289,19 +289,19 @@ public:
// NOTE: Channel numbers are zero based - they are 1 based in the xml
case 0:
DGUNIT_ASSERT_EQUAL(std::string("AmbLeft"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 1:
DGUNIT_ASSERT_EQUAL(std::string("AmbRight"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 11:
DGUNIT_ASSERT_EQUAL(std::string("SnareBottom"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
case 12:
DGUNIT_ASSERT_EQUAL(std::string("SnareTop"),
- audiofile.second->instrument_channel->name);
+ audiofile.second->instrument_channel->name);
break;
default:
DGUNIT_ASSERT(false);
diff --git a/test/drumkit_creator.cc b/test/drumkit_creator.cc
index c4d8ff1..7a0291c 100644
--- a/test/drumkit_creator.cc
+++ b/test/drumkit_creator.cc
@@ -304,7 +304,7 @@ void DrumkitCreator::createInstrument(const InstrumentData& data, std::size_t nu
const std::string& dir)
{
std::string prefix = "<?xml version='1.0' encoding='UTF-8'?>\n"
- "<instrument name=\"" + data.name + "\">\n";
+ "<instrument name=\"" + data.name + "\" version=\"2.0\">\n";
// FIXME sampleref
std::string postfix = "<velocities>\n"
"<velocity lower=\"0\" upper=\"1\">\n"
@@ -347,8 +347,8 @@ std::string DrumkitCreator::createDrumkitFile(const DrumkitData& data, const std
{
// Pre- and postfix string
std::string prefix = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- "<drumkit name=\"" + data.name + "\" description=\"An drumkit generated"
- " by the drumkit_generator\">\n";
+ "<drumkit name=\"" + data.name + "\" version=\"2.0\""
+ " description=\"An drumkit generated by the drumkit_generator\">\n";
std::string postfix = "</drumkit>\n";
// Channel string
@@ -359,7 +359,7 @@ std::string DrumkitCreator::createDrumkitFile(const DrumkitData& data, const std
channels += "<channel name=\"ch" + std::to_string(i) + "\"/>\n";
}
channels += "</channels>\n";
-
+
// Instrument string
std::string instruments;
instruments += "<instruments>\n";