diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/audiofile.cc | 18 | ||||
| -rw-r--r-- | src/audiofile.h | 13 | ||||
| -rw-r--r-- | src/channel.h | 9 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 7 | ||||
| -rw-r--r-- | src/drumkitparser.cc | 77 | ||||
| -rw-r--r-- | src/drumkitparser.h | 7 | ||||
| -rw-r--r-- | src/instrumentparser.cc | 14 | 
7 files changed, 102 insertions, 43 deletions
| diff --git a/src/audiofile.cc b/src/audiofile.cc index a8e9d4a..c2c5cf9 100644 --- a/src/audiofile.cc +++ b/src/audiofile.cc @@ -35,11 +35,14 @@  #include <hugin.hpp> -AudioFile::AudioFile(const std::string& filename, std::size_t filechannel, bool main) +#include "channel.h" + +AudioFile::AudioFile(const std::string& filename, std::size_t filechannel, +                     InstrumentChannel* instrument_channel)  	: filename(filename)  	, filechannel(filechannel) -	, main(main)  	, magic{this} +	, instrument_channel(instrument_channel)  {  } @@ -151,3 +154,14 @@ bool AudioFile::isLoaded() const  {  	return is_loaded;  } + +main_state_t AudioFile::mainState() const +{ +	if(instrument_channel == nullptr) +	{ +		DEBUG(audiofile, "no instrument_channel!"); +		return main_state_t::unset; +	} + +	return instrument_channel->main; +} diff --git a/src/audiofile.h b/src/audiofile.h index 5d6cdae..d73dad8 100644 --- a/src/audiofile.h +++ b/src/audiofile.h @@ -35,11 +35,15 @@  #include <sndfile.h>  #include "audio.h" +#include "channel.h" + +class InstrumentChannel;  class AudioFile  {  public: -	AudioFile(const std::string& filename, std::size_t filechannel, bool main = true); +	AudioFile(const std::string& filename, std::size_t filechannel, +	          InstrumentChannel* instrument_channel = nullptr);  	~AudioFile();  	void load(std::size_t sample_limit = std::numeric_limits<std::size_t>::max()); @@ -55,13 +59,16 @@ public:  	bool isValid() const; +	//! Returns if this audio file is to be played on a main channel (ie. not a +	//! secondary channel) +	main_state_t mainState() const; +  	std::mutex mutex;  	std::size_t filechannel; -	bool main; -  private:  	void* magic{nullptr};  	volatile bool is_loaded{false}; +	InstrumentChannel* instrument_channel;  }; diff --git a/src/channel.h b/src/channel.h index 52b2a9b..aaa2843 100644 --- a/src/channel.h +++ b/src/channel.h @@ -34,6 +34,13 @@  #define ALL_CHANNELS ((channel_t)0xffffffff)  #define NO_CHANNEL ((channel_t)0xfffffffe) +enum class main_state_t +{ +	unset, +	is_main, +	is_not_main +}; +  class Channel  {  public: @@ -49,7 +56,7 @@ class InstrumentChannel  public:  	InstrumentChannel(const std::string& name = ""); -	bool main{true}; +	main_state_t main{main_state_t::unset};  };  typedef std::vector<Channel> Channels; diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index dad174b..9874bbe 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -283,7 +283,8 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)  					size_t initial_chunksize = (pos + sz) - evt.offset;  					evt.buffer = audio_cache.open(af, initial_chunksize,  					                              af.filechannel, evt.cache_id); -					if(!af.main && enable_bleed_control) +					if((af.mainState() == main_state_t::is_not_main) && +					   enable_bleed_control)  					{  						evt.scale = master_bleed;  					} @@ -333,7 +334,7 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)  						for(; (n < optend) && (t < evt.buffer_size); n += N)  						{ -							*(vNsf*)&(s[n]) += *(vNsf*)&(evt.buffer[t]); +							*(vNsf*)&(s[n]) += *(vNsf*)&(evt.buffer[t]) * evt.scale;  							t += N;  						}  #endif @@ -354,7 +355,7 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)  						for(; (n < end) && (t < evt.buffer_size) && evt.rampdown; ++n)  						{  							float scale = (float)evt.rampdown/(float)evt.ramp_start; -							s[n] += evt.buffer[t]  * evt.scale * scale; +							s[n] += evt.buffer[t] * evt.scale * scale;  							++t;  							evt.rampdown--;  						} diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc index f517ef7..2a49e47 100644 --- a/src/drumkitparser.cc +++ b/src/drumkitparser.cc @@ -177,7 +177,14 @@ void DrumKitParser::startTag(const std::string& name, const attr_t& attr)  			return;  		} -		channelmap[attr.at("in")] = attr.at("out"); +		channel_attribute_t cattr{attr.at("out"), main_state_t::unset}; +		if(attr.find("main") != attr.end()) +		{ +			cattr.main_state = (attr.at("main") == "true") ? +				main_state_t::is_main : main_state_t::is_not_main; +		} + +		channelmap[attr.at("in")] = cattr;  	}  } @@ -185,43 +192,63 @@ void DrumKitParser::endTag(const std::string& name)  {  	if(name == "instrument")  	{ -		auto ptr = std::make_unique<Instrument>(settings, rand); -		ptr->setGroup(instr_group); +		{ +			// Scope the std::unique_ptr 'ptr' so we don't accidentally use it after +			// it is std::move'd to the instruments list. +			auto ptr = std::make_unique<Instrument>(settings, rand); +			ptr->setGroup(instr_group); + +			InstrumentParser parser(*ptr); +			parser.parseFile(path + "/" + instr_file); + +			// Transfer ownership to the DrumKit object. +			kit.instruments.emplace_back(std::move(ptr)); +		} + +		auto& instrument = *kit.instruments.back(); + +		// Only use main attribute from drumkit file if at least one exists. +		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); -		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. -		kit.instruments.emplace_back(std::move(ptr)); -		Instrument& instrument = *kit.instruments.back(); +			if(cattr.main_state == main_state_t::unset) +			{ +				cattr.main_state = default_main_state; +			} -		// Assign kit channel numbers to instruments channels. -		for (auto& c: instrument.instrument_channels) { -			std::string cname = c.name; -			if(channelmap.find(cname) != channelmap.end()) +			if(cattr.main_state != main_state_t::unset)  			{ -				cname = channelmap[cname]; +				instrument_channel.main = cattr.main_state;  			} -			for(std::size_t cnt = 0; cnt < kit.channels.size(); cnt++) +			for(auto cnt = 0u; cnt < kit.channels.size(); ++cnt)  			{ -				if(kit.channels[cnt].name == cname) +				if(kit.channels[cnt].name == cattr.cname)  				{ -					c.num = kit.channels[cnt].num; +					instrument_channel.num = kit.channels[cnt].num;  				}  			} -			if(c.num == NO_CHANNEL) +			if(instrument_channel.num == NO_CHANNEL)  			{  				ERR(kitparser, "Missing channel '%s' in instrument '%s'\n", -				    c.name.c_str(), instrument.getName().c_str()); -			} -			else -			{ -				/* -				  DEBUG(kitparser, "Assigned channel '%s' to number %d in instrument '%s'\n", -				  c->name.c_str(), c->num, i.name().c_str()); -				*/ +				    instrument_channel.name.c_str(), instrument.getName().c_str());  			}  		} diff --git a/src/drumkitparser.h b/src/drumkitparser.h index 5c5cf9f..e4645c3 100644 --- a/src/drumkitparser.h +++ b/src/drumkitparser.h @@ -49,7 +49,12 @@ private:  	DrumKit& kit;  	std::string path; -	std::unordered_map<std::string, std::string> channelmap; +	struct channel_attribute_t +	{ +		std::string cname; +		main_state_t main_state; +	}; +	std::unordered_map<std::string, channel_attribute_t> channelmap;  	std::string instr_file;  	std::string instr_name;  	std::string instr_group; diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc index 1f3948e..f49a6af 100644 --- a/src/instrumentparser.cc +++ b/src/instrumentparser.cc @@ -94,14 +94,13 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)  			return;  		} -		bool main = false; +		InstrumentChannel* channel = addOrGetChannel(attr.at("name")); +		channel->main = main_state_t::is_not_main;  		if(attr.find("main") != attr.end())  		{ -			main = attr.at("main") == "true"; +			channel->main = (attr.at("main") == "true") ? +				main_state_t::is_main : main_state_t::is_not_main;  		} - -		InstrumentChannel* channel = addOrGetChannel(attr.at("name")); -		channel->main = main;  	}  	if(name == "samples") @@ -169,7 +168,7 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)  		auto audio_file =  			std::make_unique<AudioFile>(path + "/" + attr.at("file"),  			                            filechannel, -			                            instrument_channel->main); +			                            instrument_channel);  		sample->addAudioFile(instrument_channel, audio_file.get()); @@ -263,8 +262,7 @@ InstrumentChannel* InstrumentParser::addOrGetChannel(const std::string& name)  	instrument.instrument_channels.emplace_back(name);  	InstrumentChannel& channel = instrument.instrument_channels.back(); -	channel.main = true; // Ad-hoc added channels are all main by default for -	                     // backwards compatibility. +	channel.main = main_state_t::unset;  	return &channel;  } | 
