diff options
| -rw-r--r-- | src/audiofile.cc | 3 | ||||
| -rw-r--r-- | src/audiofile.h | 4 | ||||
| -rw-r--r-- | src/channel.cc | 27 | ||||
| -rw-r--r-- | src/channel.h | 9 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 13 | ||||
| -rw-r--r-- | src/drumkitparser.cc | 15 | ||||
| -rw-r--r-- | src/events.h | 1 | ||||
| -rw-r--r-- | src/inputprocessor.cc | 2 | ||||
| -rw-r--r-- | src/instrument.h | 2 | ||||
| -rw-r--r-- | src/instrumentparser.cc | 58 | ||||
| -rw-r--r-- | src/instrumentparser.h | 4 | ||||
| -rw-r--r-- | src/powerlist.cc | 12 | ||||
| -rw-r--r-- | src/powerlist.h | 6 | ||||
| -rw-r--r-- | src/sample.cc | 6 | ||||
| -rw-r--r-- | src/sample.h | 7 | 
15 files changed, 105 insertions, 64 deletions
| diff --git a/src/audiofile.cc b/src/audiofile.cc index e274e61..a8e9d4a 100644 --- a/src/audiofile.cc +++ b/src/audiofile.cc @@ -35,9 +35,10 @@  #include <hugin.hpp> -AudioFile::AudioFile(const std::string& filename, std::size_t filechannel) +AudioFile::AudioFile(const std::string& filename, std::size_t filechannel, bool main)  	: filename(filename)  	, filechannel(filechannel) +	, main(main)  	, magic{this}  {  } diff --git a/src/audiofile.h b/src/audiofile.h index e393511..5d6cdae 100644 --- a/src/audiofile.h +++ b/src/audiofile.h @@ -39,7 +39,7 @@  class AudioFile  {  public: -	AudioFile(const std::string& filename, std::size_t filechannel); +	AudioFile(const std::string& filename, std::size_t filechannel, bool main = true);  	~AudioFile();  	void load(std::size_t sample_limit = std::numeric_limits<std::size_t>::max()); @@ -59,6 +59,8 @@ public:  	std::size_t filechannel; +	bool main; +  private:  	void* magic{nullptr};  	volatile bool is_loaded{false}; diff --git a/src/channel.cc b/src/channel.cc index 402a09a..812b43e 100644 --- a/src/channel.cc +++ b/src/channel.cc @@ -32,26 +32,7 @@ Channel::Channel(const std::string& name)  {  } -#ifdef TEST_CHANNEL -// deps: -// cflags: -// libs: -#include "test.h" - -TEST_BEGIN; - -Channel c1; -TEST_EQUAL_STR(c1.name, "", "Empty name?"); -TEST_EQUAL_INT(c1.num, NO_CHANNEL, "No physical channel assigned?"); - -Channel c2("ch2"); -TEST_EQUAL_STR(c2.name, "ch2", "Nonempty name?"); -TEST_EQUAL_INT(c2.num, NO_CHANNEL, "No physical channel assigned?"); - -Channels channels; -channels.push_back(c1); -channels.push_back(c2); - -TEST_END; - -#endif /*TEST_CHANNEL*/ +InstrumentChannel::InstrumentChannel(const std::string& name) +	: Channel(name) +{ +} diff --git a/src/channel.h b/src/channel.h index 6cfee81..52b2a9b 100644 --- a/src/channel.h +++ b/src/channel.h @@ -43,6 +43,13 @@ public:  	channel_t num;  }; -typedef Channel InstrumentChannel; +class InstrumentChannel +	: public Channel +{ +public: +	InstrumentChannel(const std::string& name = ""); + +	bool main{true}; +};  typedef std::vector<Channel> Channels; diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index 5fa2097..dad174b 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -248,6 +248,10 @@ typedef float vNsf __attribute__ ((vector_size(sizeof(sample_t)*N)));  void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)  { +	// Store local values of settings to ensure they don't change intra-iteration +	const auto enable_bleed_control = settings.enable_bleed_control.load(); +	const auto master_bleed = settings.master_bleed.load(); +  	std::vector< Event* > erase_list;  	std::list< Event* >::iterator i = activeevents[ch].begin();  	for(; i != activeevents[ch].end(); ++i) @@ -279,6 +283,11 @@ 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) +					{ +						evt.scale = master_bleed; +					} +  					evt.buffer_size = initial_chunksize;  				} @@ -336,7 +345,7 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)  							assert(t >= 0);  							assert(t < evt.buffer_size); -							s[n] += evt.buffer[t]; +							s[n] += evt.buffer[t] * evt.scale;  							++t;  						}  					} @@ -345,7 +354,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] * scale; +							s[n] += evt.buffer[t]  * evt.scale * scale;  							++t;  							evt.rampdown--;  						} diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc index dd79bce..f517ef7 100644 --- a/src/drumkitparser.cc +++ b/src/drumkitparser.cc @@ -187,16 +187,17 @@ void DrumKitParser::endTag(const std::string& name)  	{  		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.push_back(std::move(ptr)); +		kit.instruments.emplace_back(std::move(ptr)); +		Instrument& instrument = *kit.instruments.back();  		// Assign kit channel numbers to instruments channels. -		for (auto& c: parser.channellist) { -			std::string cname = c->name; +		for (auto& c: instrument.instrument_channels) { +			std::string cname = c.name;  			if(channelmap.find(cname) != channelmap.end())  			{  				cname = channelmap[cname]; @@ -206,14 +207,14 @@ void DrumKitParser::endTag(const std::string& name)  			{  				if(kit.channels[cnt].name == cname)  				{ -					c->num = kit.channels[cnt].num; +					c.num = kit.channels[cnt].num;  				}  			} -			if(c->num == NO_CHANNEL) +			if(c.num == NO_CHANNEL)  			{  				ERR(kitparser, "Missing channel '%s' in instrument '%s'\n", -				      c->name.c_str(), ptr->getName().c_str()); +				    c.name.c_str(), instrument.getName().c_str());  			}  			else  			{ diff --git a/src/events.h b/src/events.h index b0ca6cf..30a9e8b 100644 --- a/src/events.h +++ b/src/events.h @@ -91,6 +91,7 @@ public:  	void* instrument;  	int rampdown;  	int ramp_start; +	float scale{1.0f};  };  class EventQueue diff --git a/src/inputprocessor.cc b/src/inputprocessor.cc index af07dad..5d96e2d 100644 --- a/src/inputprocessor.cc +++ b/src/inputprocessor.cc @@ -151,7 +151,7 @@ bool InputProcessor::processOnset(event_t& event,  	for(Channel& ch: kit.channels)  	{ -		AudioFile* af = sample->getAudioFile(&ch); +		AudioFile* af = sample->getAudioFile(ch);  		if(af == nullptr || !af->isValid())  		{  			//DEBUG(inputprocessor, "Missing AudioFile.\n"); diff --git a/src/instrument.h b/src/instrument.h index 41fe886..4076b48 100644 --- a/src/instrument.h +++ b/src/instrument.h @@ -42,6 +42,7 @@  class Instrument  {  	friend class InstrumentParser; +	friend class DrumKitParser;  public:  	Instrument(Settings& settings, Random& rand);  	~Instrument(); @@ -78,6 +79,7 @@ private:  	void finalise(); ///< Signal instrument that no more samples will be added.  	std::vector<Sample*> samplelist; +	std::vector<InstrumentChannel> instrument_channels;  	size_t lastpos;  	float mod; diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc index 45e76d8..1f3948e 100644 --- a/src/instrumentparser.cc +++ b/src/instrumentparser.cc @@ -82,6 +82,28 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)  		}  	} +	if(name == "channels") +	{ +	} + +	if(name == "channel") +	{ +		if(attr.find("name") == attr.end()) +		{ +			ERR(instrparser,"Missing channel required attribute 'name'.\n"); +			return; +		} + +		bool main = false; +		if(attr.find("main") != attr.end()) +		{ +			main = attr.at("main") == "true"; +		} + +		InstrumentChannel* channel = addOrGetChannel(attr.at("name")); +		channel->main = main; +	} +  	if(name == "samples")  	{  	} @@ -142,19 +164,13 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)  		filechannel = filechannel - 1; // 1-based in file but zero-based internally. -		auto audio_file = std::make_unique<AudioFile>(path + "/" + attr.at("file"), filechannel); +		InstrumentChannel *instrument_channel = addOrGetChannel(attr.at("channel")); -		// note: memory leak! the channels are never released -		// once I replaced this using unique_ptr, the channels were -		// destroyed when the InstrumentParser went out of scope -		// (see drumkitparser.cc, where the InstrumentParser lives in -		// local scope). -		// so.. we cannot replace this using smart ptr until we decided -		// the ownership semantics for instances InstrumentChannel -		InstrumentChannel *instrument_channel = -			new InstrumentChannel(attr.at("channel")); +		auto audio_file = +			std::make_unique<AudioFile>(path + "/" + attr.at("file"), +			                            filechannel, +			                            instrument_channel->main); -		channellist.push_back(instrument_channel);  		sample->addAudioFile(instrument_channel, audio_file.get());  		// Transfer audio_file ownership to the instrument. @@ -203,7 +219,7 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)  		if(sample_ref == nullptr)  		{ -			ERR(instrparser,"Samplref pointed at non-existing sample.\n"); +			ERR(instrparser,"Sampleref pointed at non-existing sample.\n");  			return;  		} @@ -234,3 +250,21 @@ void InstrumentParser::endTag(const std::string& name)  		instrument.finalise();  	}  } + +InstrumentChannel* InstrumentParser::addOrGetChannel(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 = true; // Ad-hoc added channels are all main by default for +	                     // backwards compatibility. + +	return &channel; +} diff --git a/src/instrumentparser.h b/src/instrumentparser.h index 512f12f..e87489f 100644 --- a/src/instrumentparser.h +++ b/src/instrumentparser.h @@ -41,13 +41,15 @@ public:  	virtual int parseFile(const std::string& filename) override; -	std::vector<InstrumentChannel*> channellist; +	std::vector<InstrumentChannel> channellist;  protected:  	virtual void startTag(const std::string& name, const attr_t& attr) override;  	virtual void endTag(const std::string& name) override;  private: +	InstrumentChannel* addOrGetChannel(const std::string& name); +  	Instrument& instrument;  	Sample* sample{nullptr}; diff --git a/src/powerlist.cc b/src/powerlist.cc index b502d03..b5e7c84 100644 --- a/src/powerlist.cc +++ b/src/powerlist.cc @@ -67,19 +67,19 @@ void PowerList::add(Sample* sample)  	samples.push_back(item);  } -Channel* PowerList::getMasterChannel() +const Channel* PowerList::getMasterChannel()  { -	std::map<Channel*, int> count; +	std::map<const Channel*, int> count;  	for (auto& item: samples)  	{  		Sample* sample{item.sample}; -		Channel* max_channel{nullptr}; +		const Channel* max_channel{nullptr};  		sample_t max_val{0};  		for (auto& pair: sample->audiofiles)  		{ -			Channel* c = pair.first; +			const Channel* c = pair.first;  			AudioFile* af = pair.second;  			af->load(LOAD_SIZE); @@ -116,7 +116,7 @@ Channel* PowerList::getMasterChannel()  		}  	} -	Channel* master{nullptr}; +	const Channel* master{nullptr};  	int max_count{-1};  	for (auto& pair: count) @@ -134,7 +134,7 @@ Channel* PowerList::getMasterChannel()  void PowerList::finalise()  {  #ifdef AUTO_CALCULATE_POWER -	Channel* master_channel = getMasterChannel(); +	const Channel* master_channel = getMasterChannel();  	if(master_channel == nullptr)  	{ diff --git a/src/powerlist.h b/src/powerlist.h index ff360b4..9066ce1 100644 --- a/src/powerlist.h +++ b/src/powerlist.h @@ -38,7 +38,7 @@ public:  	void add(Sample* s);  	void finalise(); ///< Call this when no more samples will be added. -	 +  	Sample* get(level_t velocity);  private: @@ -53,7 +53,7 @@ private:  	std::vector<PowerListItem> samples;  	float power_max;  	float power_min; -	 -	Channel* getMasterChannel(); + +	const Channel* getMasterChannel();  	Sample* lastsample;  }; diff --git a/src/sample.cc b/src/sample.cc index 9d28a17..1f624d3 100644 --- a/src/sample.cc +++ b/src/sample.cc @@ -39,12 +39,12 @@ Sample::~Sample()  {  } -void Sample::addAudioFile(Channel* c, AudioFile* a) +void Sample::addAudioFile(InstrumentChannel* c, AudioFile* a)  {  	audiofiles[c] = a;  } -AudioFile* Sample::getAudioFile(Channel* c) +AudioFile* Sample::getAudioFile(const Channel& channel)  {  	/*  	if(audiofiles.find(c) == audiofiles.end()) return nullptr; @@ -54,7 +54,7 @@ AudioFile* Sample::getAudioFile(Channel* c)  	// todo: std::find_if ??  	for (auto& pair: audiofiles)  	{ -		if (pair.first->num == c->num) +		if (pair.first->num == channel.num)  		{  			return pair.second;  		} diff --git a/src/sample.h b/src/sample.h index f00db13..e9cbf18 100644 --- a/src/sample.h +++ b/src/sample.h @@ -32,16 +32,17 @@  #include "channel.h"  #include "audiofile.h" -using AudioFiles = std::map<Channel*, AudioFile*>; +using AudioFiles = std::map<const InstrumentChannel*, AudioFile*>; -class Sample { +class Sample +{  	friend class InstrumentParser;  	friend class PowerList;  public:  	Sample(const std::string& name, float power);  	~Sample(); -	AudioFile* getAudioFile(InstrumentChannel *instrument_channel); +	AudioFile* getAudioFile(const Channel& channel);  private:  	void addAudioFile(InstrumentChannel* instrument_channel, | 
