From bd0e48a876f25751ae7e0d025178b19d773ca00e Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 17 Jun 2018 15:26:07 +0200 Subject: Finished DOMLoader and fixed the broken unit-tests. --- src/DGDOM.h | 3 ++ src/dgxmlparser.cc | 10 ++-- src/domloader.cc | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++--- src/domloader.h | 6 +++ src/instrument.cc | 2 + 5 files changed, 155 insertions(+), 9 deletions(-) (limited to 'src') 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 samples; std::vector 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 + +#include + #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& 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(settings, random); - ptr->setGroup(instrumentref.group); + bool found{found}; + + std::unordered_map 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(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(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 +#include 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(); -- cgit v1.2.3