summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2017-09-03 14:08:41 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2017-09-03 14:08:41 +0200
commit1c25d3a69ac27dc1f93bca3a71996e757b452c4b (patch)
treea67541f62bd35577003f812b35ab6a35098e36ae /src
parenta359d234ff53bcdab671faa169f45c4f14f5575d (diff)
Add bleed controls for the drumkit with priority over those set in the instrument files.
Diffstat (limited to 'src')
-rw-r--r--src/audiofile.cc18
-rw-r--r--src/audiofile.h13
-rw-r--r--src/channel.h9
-rw-r--r--src/drumgizmo.cc7
-rw-r--r--src/drumkitparser.cc77
-rw-r--r--src/drumkitparser.h7
-rw-r--r--src/instrumentparser.cc14
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;
}