diff options
-rw-r--r-- | src/DGDOM.h | 3 | ||||
-rw-r--r-- | src/dgxmlparser.cc | 10 | ||||
-rw-r--r-- | src/domloader.cc | 143 | ||||
-rw-r--r-- | src/domloader.h | 6 | ||||
-rw-r--r-- | src/instrument.cc | 2 | ||||
-rw-r--r-- | test/dgxmlparsertest.cc | 7 | ||||
-rw-r--r-- | test/domloadertest.cc | 40 | ||||
-rw-r--r-- | test/drumkit_creator.cc | 8 |
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"; |