summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2021-01-26 20:31:31 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2022-02-05 12:34:49 +0100
commit47833d52f6e9f8d3d68d0b22ca8fd31dde09e4b1 (patch)
tree829c77c301e257174e5591a27e0870c05e89edec
parent235ad6fbbce2e0ae9e06db960a5ba3b099936ace (diff)
Add positional information to drumkit xml and sample class.
-rw-r--r--src/DGDOM.h1
-rw-r--r--src/audioinputenginemidi.cc77
-rw-r--r--src/audioinputenginemidi.h2
-rw-r--r--src/dgxmlparser.cc16
-rw-r--r--src/domloader.cc1
-rw-r--r--src/event.h9
-rw-r--r--src/sample.cc9
-rw-r--r--src/sample.h5
8 files changed, 86 insertions, 34 deletions
diff --git a/src/DGDOM.h b/src/DGDOM.h
index 474b29c..a03f0ef 100644
--- a/src/DGDOM.h
+++ b/src/DGDOM.h
@@ -59,6 +59,7 @@ struct SampleDOM
{
std::string name;
double power; // >= v2.0 only
+ double position; // >=v2.0 only
bool normalized; // >= v2.0 only
std::vector<AudioFileDOM> audiofiles;
};
diff --git a/src/audioinputenginemidi.cc b/src/audioinputenginemidi.cc
index 69aeeb6..0dee346 100644
--- a/src/audioinputenginemidi.cc
+++ b/src/audioinputenginemidi.cc
@@ -100,9 +100,13 @@ bool AudioInputEngineMidi::isValid() const
static const std::uint8_t NoteOff = 0x80;
static const std::uint8_t NoteOn = 0x90;
static const std::uint8_t NoteAftertouch = 0xA0;
+static const std::uint8_t ControlChange = 0xB0;
// Note type mask:
-static int const NoteMask = 0xF0;
+static const std::uint8_t TypeMask = 0xF0;
+
+// See:
+// https://www.midi.org/specifications-old/item/table-1-summary-of-midi-message
void AudioInputEngineMidi::processNote(const std::uint8_t* midi_buffer,
std::size_t midi_buffer_length,
@@ -114,38 +118,61 @@ void AudioInputEngineMidi::processNote(const std::uint8_t* midi_buffer,
return;
}
- auto key = midi_buffer[1];
- auto velocity = midi_buffer[2];
- auto instrument_idx = mmap.lookup(key);
- auto instruments = mmap.lookup(key);
- for(const auto& instrument_idx : instruments)
+ switch(midi_buffer[0] & TypeMask)
{
- switch(midi_buffer[0] & NoteMask)
- {
- case NoteOff:
- // Ignore for now
- break;
+ case NoteOff:
+ // Ignore for now
+ break;
- case NoteOn:
- if(velocity != 0)
+ case NoteOn:
+ {
+ auto key = midi_buffer[1];
+ auto velocity = midi_buffer[2];
+ auto instruments = mmap.lookup(key);
+ for(const auto& instrument_idx : instruments)
{
- // maps velocities to [.5/127, 126.5/127]
- auto centered_velocity = (velocity-.5f)/127.0f;
- events.push_back({EventType::OnSet, (std::size_t)instrument_idx,
- offset, centered_velocity});
+ if(velocity != 0)
+ {
+ // maps velocities to [.5/127, 126.5/127]
+ auto centered_velocity = (velocity-.5f)/127.0f;
+ events.push_back({EventType::OnSet, (std::size_t)instrument_idx,
+ offset, centered_velocity, positional_information});
+ }
}
- break;
+ }
+ break;
- case NoteAftertouch:
- if(velocity > 0)
+ case NoteAftertouch:
+ {
+ auto key = midi_buffer[1];
+ auto velocity = midi_buffer[2];
+ auto instruments = mmap.lookup(key);
+ for(const auto& instrument_idx : instruments)
{
- events.push_back({EventType::Choke, (std::size_t)instrument_idx,
- offset, .0f});
+ if(velocity > 0)
+ {
+ events.push_back({EventType::Choke, (std::size_t)instrument_idx,
+ offset, .0f, .0f});
+ }
}
- break;
+ }
+ break;
- default:
- break;
+ case ControlChange:
+ {
+ auto controller_number = midi_buffer[1];
+ auto value = midi_buffer[2];
+ if(controller_number == 16) // positional information
+ {
+ // Store value for use in next NoteOn event.
+ positional_information = value / 127.0f;
+
+ // Return here to prevent reset of cached positional information.
+ return;
+ }
}
}
+
+ // Clear cached positional information.
+ positional_information = 0.0f;
}
diff --git a/src/audioinputenginemidi.h b/src/audioinputenginemidi.h
index 8da7bd2..12efd66 100644
--- a/src/audioinputenginemidi.h
+++ b/src/audioinputenginemidi.h
@@ -70,4 +70,6 @@ private:
bool is_valid;
ConfigFile refs;
+
+ float positional_information{0.0f};
};
diff --git a/src/dgxmlparser.cc b/src/dgxmlparser.cc
index 0d3cdcd..bd9af66 100644
--- a/src/dgxmlparser.cc
+++ b/src/dgxmlparser.cc
@@ -358,9 +358,19 @@ bool parseInstrumentFile(const std::string& filename, InstrumentDOM& dom, LogFun
}
else
{
- res &= attrcpy(dom.samples.back().power, sample, "power", logger, filename);
- dom.samples.back().normalized = false;
- res &= attrcpy(dom.samples.back().normalized, sample, "normalized", logger, filename, true);
+ res &= attrcpy(dom.samples.back().power, sample, "power",
+ logger, filename);
+
+ dom.samples.back().position = 0.0; // optional - defaults to 0
+ res &= attrcpy(dom.samples.back().position, sample, "position",
+ logger, filename, true);
+ // Clamp to [0; 1] range.
+ dom.samples.back().position =
+ std::min(1.0, std::max(dom.samples.back().position, 0.0));
+
+ dom.samples.back().normalized = false; // optional - defaults to false
+ res &= attrcpy(dom.samples.back().normalized, sample, "normalized",
+ logger, filename, true);
}
for(pugi::xml_node audiofile: sample.children("audiofile"))
diff --git a/src/domloader.cc b/src/domloader.cc
index c78ed75..5d411bd 100644
--- a/src/domloader.cc
+++ b/src/domloader.cc
@@ -99,6 +99,7 @@ bool DOMLoader::loadDom(const std::string& basepath,
for(const auto& sampledom : instrumentdom.samples)
{
auto sample = new Sample(sampledom.name, sampledom.power,
+ sampledom.position,
sampledom.normalized);
for(const auto& audiofiledom : sampledom.audiofiles)
{
diff --git a/src/event.h b/src/event.h
index 737fb18..5780cc9 100644
--- a/src/event.h
+++ b/src/event.h
@@ -39,8 +39,9 @@ enum class EventType
//! POD datatype for input event transport.
struct event_t
{
- EventType type; //!< The type of the event.
- std::size_t instrument; //!< The instrument number.
- std::size_t offset; //!< The offset position in the input buffer
- float velocity; //!< The velocity if the type is a note on [0; 1]
+ EventType type; //!< The type of the event.
+ std::size_t instrument; //!< The instrument number.
+ std::size_t offset; //!< The offset position in the input buffer
+ float velocity; //!< The velocity if the type is a note on [0; 1]
+ float position; //!< The position of the note. 0 := center, 1 := rim
};
diff --git a/src/sample.cc b/src/sample.cc
index 9af2c08..2c59f5e 100644
--- a/src/sample.cc
+++ b/src/sample.cc
@@ -28,9 +28,11 @@
#include <sndfile.h>
-Sample::Sample(const std::string& name, double power, bool normalized)
+Sample::Sample(const std::string& name, double power, double position,
+ bool normalized)
: name{name}
, power{power}
+ , position{position}
, normalized(normalized)
, audiofiles{}
{
@@ -69,6 +71,11 @@ double Sample::getPower() const
return power;
}
+double Sample::getPosition() const
+{
+ return position;
+}
+
bool Sample::getNormalized() const
{
return normalized;
diff --git a/src/sample.h b/src/sample.h
index 6c31b6b..b13f624 100644
--- a/src/sample.h
+++ b/src/sample.h
@@ -37,12 +37,14 @@ using AudioFiles = std::map<const InstrumentChannel*, AudioFile*>;
class Sample
{
public:
- Sample(const std::string& name, double power, bool normalized = false);
+ Sample(const std::string& name, double power, double position,
+ bool normalized = false);
~Sample();
AudioFile* getAudioFile(const Channel& channel) const;
double getPower() const;
+ double getPosition() const;
bool getNormalized() const;
private:
@@ -55,6 +57,7 @@ private:
std::string name;
double power;
+ double position{0.0};
bool normalized;
AudioFiles audiofiles;
};