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"; | 
