diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2019-03-17 11:44:21 +0100 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2019-03-17 11:44:21 +0100 | 
| commit | 5dee5069bc10ba3e190723aa68bb880183b1dc4c (patch) | |
| tree | 9de9f8f3d328c7a1d62540e63ac448d3ed4dd90f /src | |
| parent | 5eb47bed81de1326843e1e3bad41addcfed08d4e (diff) | |
Implemented new directed choke feature.
Diffstat (limited to 'src')
| -rw-r--r-- | src/DGDOM.h | 7 | ||||
| -rw-r--r-- | src/dgxmlparser.cc | 40 | ||||
| -rw-r--r-- | src/domloader.cc | 54 | ||||
| -rw-r--r-- | src/events.h | 6 | ||||
| -rw-r--r-- | src/inputprocessor.cc | 48 | ||||
| -rw-r--r-- | src/instrument.cc | 10 | ||||
| -rw-r--r-- | src/instrument.h | 12 | 
7 files changed, 154 insertions, 23 deletions
| diff --git a/src/DGDOM.h b/src/DGDOM.h index dea4228..1adf391 100644 --- a/src/DGDOM.h +++ b/src/DGDOM.h @@ -95,12 +95,19 @@ struct ChannelMapDOM  	main_state_t main;  }; +struct ChokeDOM +{ +	std::string instrument; +	double choketime; +}; +  struct InstrumentRefDOM  {  	std::string name;  	std::string file; // Probably shouldn't be there  	std::string group;  	std::vector<ChannelMapDOM> channel_map; +	std::vector<ChokeDOM> chokes;  };  struct ClickMapDOM diff --git a/src/dgxmlparser.cc b/src/dgxmlparser.cc index 28e183a..ae0842a 100644 --- a/src/dgxmlparser.cc +++ b/src/dgxmlparser.cc @@ -193,18 +193,40 @@ bool parseDrumkitFile(const std::string& filename, DrumkitDOM& dom)  	for(pugi::xml_node instrument : instruments.children("instrument"))  	{  		dom.instruments.emplace_back(); - -		res &= attrcpy(dom.instruments.back().name, instrument, "name"); -		res &= attrcpy(dom.instruments.back().file, instrument, "file"); -		res &= attrcpy(dom.instruments.back().group, instrument, "group", true); +		auto& instrument_ref = dom.instruments.back(); +		res &= attrcpy(instrument_ref.name, instrument, "name"); +		res &= attrcpy(instrument_ref.file, instrument, "file"); +		res &= attrcpy(instrument_ref.group, instrument, "group", true);  		for(pugi::xml_node cmap: instrument.children("channelmap"))  		{ -			dom.instruments.back().channel_map.emplace_back(); -			res &= attrcpy(dom.instruments.back().channel_map.back().in, cmap, "in"); -			res &= attrcpy(dom.instruments.back().channel_map.back().out, cmap, "out"); -			dom.instruments.back().channel_map.back().main = main_state_t::unset; -			res &= attrcpy(dom.instruments.back().channel_map.back().main, cmap, "main", true); +			instrument_ref.channel_map.emplace_back(); +			auto& channel_map_ref = instrument_ref.channel_map.back(); +			res &= attrcpy(channel_map_ref.in, cmap, "in"); +			res &= attrcpy(channel_map_ref.out, cmap, "out"); +			channel_map_ref.main = main_state_t::unset; +			res &= attrcpy(channel_map_ref.main, cmap, "main", true); +		} + +		auto num_chokes = std::distance(instrument.children("chokes").begin(), +		                                instrument.children("chokes").end()); +		if(num_chokes > 1) +		{ +			// error +			ERR(dgxmlparser, "At most one 'chokes' node allowed pr. instrument."); +			res = false; +		} + +		if(num_chokes == 1) +		{ +			for(pugi::xml_node choke : instrument.child("chokes").children("choke")) +			{ +				instrument_ref.chokes.emplace_back(); +				auto& choke_ref = instrument_ref.chokes.back(); +				res &= attrcpy(choke_ref.instrument, choke, "instrument"); +				choke_ref.choketime = 68; // default to 68 ms +				res &= attrcpy(choke_ref.choketime, choke, "choketime", true); +			}  		}  	} diff --git a/src/domloader.cc b/src/domloader.cc index ad97165..0e06239 100644 --- a/src/domloader.cc +++ b/src/domloader.cc @@ -68,6 +68,9 @@ bool DOMLoader::loadDom(const std::string& basepath,  		drumkit.channels.back().num = drumkit.channels.size() - 1;  	} +	// Pass 1 - handling everything that is instrument name based and ultimately +	// inserts the instrument into the drumkit instrument list which results in +	// it getting an instrument id (ie. the index in the list).  	for(const auto& instrumentref : dom.instruments)  	{  		bool found{false}; @@ -198,6 +201,7 @@ bool DOMLoader::loadDom(const std::string& basepath,  			// Transfer ownership to the DrumKit object.  			drumkit.instruments.emplace_back(std::move(instrument)); +			drumkit.instruments.back()->id = drumkit.instruments.size() - 1;  			found = true;  		} @@ -209,6 +213,56 @@ bool DOMLoader::loadDom(const std::string& basepath,  		}  	} +	// Pass 2 - handle nodes that require instrument name to instrument id +	// mappings +	for(const auto& instrumentref : dom.instruments) +	{ +		std::size_t instr_id{0}; +		{ +			bool found{false}; +			for(std::size_t idx = 0; idx < drumkit.instruments.size(); ++idx) +			{ +				if(drumkit.instruments[idx]->getName() == instrumentref.name) +				{ +					instr_id = idx; +					found = true; +					break; +				} +			} + +			if(!found) +			{ +				// Missing instrument - skip +				continue; +			} +		} + +		for(const auto& choke : instrumentref.chokes) +		{ +			std::size_t choke_instr_id{0}; +			bool choke_found{false}; +			for(std::size_t idx = 0; idx < drumkit.instruments.size(); ++idx) +			{ +				if(drumkit.instruments[idx]->getName() == choke.instrument) +				{ +					choke_instr_id = idx; +					choke_found = true; +					break; +				} +			} + +			if(!choke_found) +			{ +				// Missing choke target instrument - skip +				continue; +			} + +			drumkit.instruments[instr_id]->chokes.emplace_back(); +			drumkit.instruments[instr_id]->chokes.back().instrument_id = choke_instr_id; +			drumkit.instruments[instr_id]->chokes.back().choketime = choke.choketime; +		} +	} +  	return true;  } diff --git a/src/events.h b/src/events.h index f43fbe2..18f9af3 100644 --- a/src/events.h +++ b/src/events.h @@ -65,16 +65,16 @@ class EventSample  {  public:  	EventSample(channel_t c, float g, AudioFile* af, -	            const std::string& grp, void* instr) +	            const std::string& grp, std::size_t instrument_id)  		: Event(c)  		, cache_id(CACHE_NOID)  		, gain(g)  		, t(0)  		, file(af)  		, group(grp) -		, instrument(instr)  		, rampdown_count(-1)  		, ramp_length(0) +		, instrument_id(instrument_id)  	{  	} @@ -98,11 +98,11 @@ public:  	unsigned int t; //< Internal sample position.  	AudioFile* file;  	std::string group; -	void* instrument;  	int rampdown_count;  	int ramp_length;  	std::size_t rampdown_offset{0};  	float scale{1.0f}; +	std::size_t instrument_id;  };  class EventQueue diff --git a/src/inputprocessor.cc b/src/inputprocessor.cc index 1570afe..1a3246c 100644 --- a/src/inputprocessor.cc +++ b/src/inputprocessor.cc @@ -95,17 +95,17 @@ bool InputProcessor::processOnset(event_t& event,  		return false;  	} -	std::size_t ev_instr = event.instrument; +	std::size_t instrument_id = event.instrument;  	Instrument* instr = nullptr; -	if(ev_instr < kit.instruments.size()) +	if(instrument_id < kit.instruments.size())  	{ -		instr = kit.instruments[ev_instr].get(); +		instr = kit.instruments[instrument_id].get();  	}  	if(instr == nullptr || !instr->isValid())  	{ -		ERR(inputprocessor, "Missing Instrument %d.\n", (int)ev_instr); +		ERR(inputprocessor, "Missing Instrument %d.\n", (int)instrument_id);  		return false;  	} @@ -124,19 +124,18 @@ bool InputProcessor::processOnset(event_t& event,  	if(instr->getGroup() != "")  	{  		// Add event to ramp down all existing events with the same groupname. -		for(Channel& ch: kit.channels) +		for(const auto& ch : kit.channels)  		{ -			for(Event* active_event: activeevents[ch.num]) +			for(auto active_event : activeevents[ch.num])  			{  				if(active_event->getType() == Event::sample)  				{  					auto& event_sample = *static_cast<EventSample*>(active_event);  					if(event_sample.group == instr->getGroup() && -					   event_sample.instrument != instr) +					   event_sample.instrument_id != instrument_id && +					   event_sample.rampdown_count == -1) // Only if not already ramping.  					{ -						// Fixed ramp of 68ms, independent of samplerate -						// TODO: This must be configurable at some point... -						// ... perhaps even by instrument (ie. in the xml file) +						// Fixed group rampdown time of 68ms, independent of samplerate  						std::size_t ramp_length = (68./1000.)*settings.samplerate.load();  						event_sample.rampdown_count = ramp_length;  						event_sample.rampdown_offset = event.offset; @@ -147,6 +146,32 @@ bool InputProcessor::processOnset(event_t& event,  		}  	} +	for(const auto& choke : instr->getChokes()) +	{ +		// Add event to ramp down all existing events with the same groupname. +		for(const auto& ch : kit.channels) +		{ +			for(auto active_event : activeevents[ch.num]) +			{ +				if(active_event->getType() == Event::sample) +				{ +					auto& event_sample = *static_cast<EventSample*>(active_event); +					if(choke.instrument_id == event_sample.instrument_id && +					   event_sample.rampdown_count == -1) // Only if not already ramping. +					{ +						// Choketime is in ms +						std::size_t ramp_length = +							(choke.choketime / 1000.0) * settings.samplerate.load(); +						event_sample.rampdown_count = ramp_length; +						event_sample.rampdown_offset = event.offset; +						event_sample.ramp_length = ramp_length; +					} +				} +			} +		} + +	} +  	const auto sample = instr->sample(event.velocity, event.offset + pos);  	if(sample == nullptr) @@ -170,7 +195,8 @@ bool InputProcessor::processOnset(event_t& event,  		else  		{  			//DEBUG(inputprocessor, "Adding event %d.\n", event.offset); -			Event* evt = new EventSample(ch.num, 1.0, af, instr->getGroup(), instr); +			Event* evt = new EventSample(ch.num, 1.0, af, instr->getGroup(), +			                             instrument_id);  			evt->offset = (event.offset + pos) * resample_ratio;  			activeevents[ch.num].push_back(evt);  		} diff --git a/src/instrument.cc b/src/instrument.cc index 29619d8..6cc4ee9 100644 --- a/src/instrument.cc +++ b/src/instrument.cc @@ -94,6 +94,11 @@ void Instrument::finalise()  	}  } +std::size_t Instrument::getID() const +{ +	return id; +} +  const std::string& Instrument::getName() const  {  	return _name; @@ -146,3 +151,8 @@ float Instrument::getMinPower() const  		return 0.0f;  	}  } + +const std::vector<Choke>& Instrument::getChokes() +{ +	return chokes; +} diff --git a/src/instrument.h b/src/instrument.h index 125d7ab..e4cf481 100644 --- a/src/instrument.h +++ b/src/instrument.h @@ -40,6 +40,12 @@  #include "settings.h" +struct Choke +{ +	std::size_t instrument_id; +	double choketime; +}; +  class Instrument  {  public: @@ -48,6 +54,7 @@ public:  	const Sample* sample(level_t level, size_t pos); +	std::size_t getID() const;  	const std::string& getName() const;  	const std::string& getDescription() const;  	const std::string& getGroup() const; @@ -66,6 +73,8 @@ public:  	float getMaxPower() const;  	float getMinPower() const; +	const std::vector<Choke>& getChokes(); +  private:  	// For unit-tests:  	friend class DOMLoaderTest; @@ -75,6 +84,7 @@ private:  	void* magic; +	std::size_t id;  	std::string _group;  	std::string _name;  	std::string _description; @@ -94,6 +104,8 @@ private:  	Settings& settings;  	Random& rand;  	PowerList powerlist; + +	std::vector<Choke> chokes;  };  // typedef std::map< std::string, Instrument > Instruments; | 
