summaryrefslogtreecommitdiff
path: root/src
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 /src
parent8dd1ea54a2d2198004c82fe75b45714917b440a1 (diff)
Finished DOMLoader and fixed the broken unit-tests.
Diffstat (limited to 'src')
-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
5 files changed, 155 insertions, 9 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();