diff options
| -rw-r--r-- | src/DGDOM.h | 2 | ||||
| -rw-r--r-- | src/channel.h | 2 | ||||
| -rw-r--r-- | src/dgxmlparser.cc | 9 | ||||
| -rw-r--r-- | src/domloader.cc | 2 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 58 | ||||
| -rw-r--r-- | src/settings.h | 9 | 
6 files changed, 81 insertions, 1 deletions
diff --git a/src/DGDOM.h b/src/DGDOM.h index 474b29c..7d2bbc6 100644 --- a/src/DGDOM.h +++ b/src/DGDOM.h @@ -87,6 +87,8 @@ struct InstrumentDOM  struct ChannelDOM  {  	std::string name; +	double stereo_panning; +	double stereo_volume;  };  struct ChannelMapDOM diff --git a/src/channel.h b/src/channel.h index aaa2843..fcc43e7 100644 --- a/src/channel.h +++ b/src/channel.h @@ -47,6 +47,8 @@ public:  	Channel(const std::string& name = "");  	std::string name; +	double stereo_panning; //! [-1; 1] where -1 i left, 0 is center and 1 is right +	double stereo_volume; //! [0; 1] volume scalar  	channel_t num;  }; diff --git a/src/dgxmlparser.cc b/src/dgxmlparser.cc index 0d3cdcd..983c2fd 100644 --- a/src/dgxmlparser.cc +++ b/src/dgxmlparser.cc @@ -256,7 +256,14 @@ bool parseDrumkitFile(const std::string& filename, DrumkitDOM& dom, LogFunction  	for(pugi::xml_node channel: channels.children("channel"))  	{  		dom.channels.emplace_back(); -		res &= attrcpy(dom.channels.back().name, channel, "name", logger, filename); +		auto& ch = dom.channels.back(); +		res &= attrcpy(ch.name, channel, "name", logger, filename); +		ch.stereo_panning = 0.0f; +		ch.stereo_volume = 1.0f; +		res &= attrcpy(ch.stereo_panning, channel, "stereo_panning", +		               logger, filename, true); +		res &= attrcpy(ch.stereo_volume, channel, "stereo_volume", +		               logger, filename, true);  	}  	pugi::xml_node instruments = doc.child("drumkit").child("instruments"); diff --git a/src/domloader.cc b/src/domloader.cc index c78ed75..bc5eea1 100644 --- a/src/domloader.cc +++ b/src/domloader.cc @@ -65,6 +65,8 @@ bool DOMLoader::loadDom(const std::string& basepath,  	{  		drumkit.channels.emplace_back();  		drumkit.channels.back().name = channel.name; +		drumkit.channels.back().stereo_panning = channel.stereo_panning; +		drumkit.channels.back().stereo_volume = channel.stereo_volume;  		drumkit.channels.back().num = drumkit.channels.size() - 1;  	} diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index ca91c12..a67dace 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -185,6 +185,63 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)  	//  	// Write audio  	// +	if(settings.enable_stereo_mode) +	{ +		static sample_t left[4096]; +		static sample_t right[4096]; +		std::memset(left, 0, sizeof(left)); +		std::memset(right, 0, sizeof(right)); +		for(size_t c = 0; c < kit.channels.size(); ++c) +		{ +			const auto& channel = kit.channels[c]; +			(void)channel; +			const auto pan = channel.stereo_panning * 0.5 + 0.5; // -> [0; 1] +			const auto scale = channel.stereo_volume; +			static sample_t buf[4096]; +			std::memset(buf, 0, sizeof(buf)); +			getSamples(c, pos, buf, nsamples); +			for(auto i = 0u; i < nsamples; ++i) +			{ +				left[i] += buf[i] * pan * scale; +				right[i] += buf[i] * (1 - pan) * scale; +			} +		} + +		for(size_t c = 0; c < kit.channels.size(); ++c) +		{ +			sample_t *buf = samples; +			bool internal = false; +			if(oe.getBuffer(c)) +			{ +				buf = oe.getBuffer(c); +				internal = true; +			} + +			if(buf) +			{ +				if(c == 0) // left channel +				{ +					memcpy(buf, left, nsamples * sizeof(sample_t)); +				} +				else if(c == 1) // right channel +				{ +					memcpy(buf, right, nsamples * sizeof(sample_t)); +				} +				else +				{ +					std::memset(buf, 0, nsamples * sizeof(sample_t)); +				} + +				if(!internal) +				{ +					oe.run(c, samples, nsamples); +				} +			} +		} + +	} +	else +	{  	if(!enable_resampling || ratio == 1.0)  	{  		// No resampling needed @@ -250,6 +307,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)  			}  		}  	} +	}  	ie.post();  	oe.post(nsamples); diff --git a/src/settings.h b/src/settings.h index 7507827..39c3534 100644 --- a/src/settings.h +++ b/src/settings.h @@ -174,6 +174,8 @@ struct Settings  	// Time it takes for an old sample to completely fall silent.  	static float constexpr voice_limit_rampdown_default = 0.5f;  	Atomic<float> voice_limit_rampdown{voice_limit_rampdown_default}; + +	Atomic<bool> enable_stereo_mode{true};  };  //! Settings getter class. @@ -256,6 +258,8 @@ struct SettingsGetter  	SettingRef<std::size_t> voice_limit_max;  	SettingRef<float> voice_limit_rampdown; +	SettingRef<bool> enable_stereo_mode; +  	SettingsGetter(Settings& settings)  		: drumkit_file(settings.drumkit_file)  		, drumkit_load_status(settings.drumkit_load_status) @@ -316,6 +320,7 @@ struct SettingsGetter  		, enable_voice_limit{settings.enable_voice_limit}  		, voice_limit_max{settings.voice_limit_max}  		, voice_limit_rampdown{settings.voice_limit_rampdown} +		, enable_stereo_mode{settings.enable_stereo_mode}  	{  	}  }; @@ -399,6 +404,8 @@ public:  	Notifier<std::size_t> voice_limit_max;  	Notifier<float> voice_limit_rampdown; +	Notifier<bool> enable_stereo_mode; +  	void evaluate()  	{  #define EVAL(x) if(settings.x.hasChanged()) { x(settings.x.getValue()); } @@ -477,6 +484,8 @@ public:  		EVAL(enable_voice_limit);  		EVAL(voice_limit_max);  		EVAL(voice_limit_rampdown); + +		EVAL(enable_stereo_mode);  	}  	SettingsNotifier(Settings& settings)  | 
