diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2021-01-26 20:31:31 +0100 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2022-02-05 12:34:49 +0100 |
commit | 47833d52f6e9f8d3d68d0b22ca8fd31dde09e4b1 (patch) | |
tree | 829c77c301e257174e5591a27e0870c05e89edec | |
parent | 235ad6fbbce2e0ae9e06db960a5ba3b099936ace (diff) |
Add positional information to drumkit xml and sample class.
-rw-r--r-- | src/DGDOM.h | 1 | ||||
-rw-r--r-- | src/audioinputenginemidi.cc | 77 | ||||
-rw-r--r-- | src/audioinputenginemidi.h | 2 | ||||
-rw-r--r-- | src/dgxmlparser.cc | 16 | ||||
-rw-r--r-- | src/domloader.cc | 1 | ||||
-rw-r--r-- | src/event.h | 9 | ||||
-rw-r--r-- | src/sample.cc | 9 | ||||
-rw-r--r-- | src/sample.h | 5 |
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; }; |