From 27cd372b72c8108260eb5198d43d059ecbff2a77 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 3 Oct 2023 09:45:35 +0200 Subject: fix issue with hi-hat choking on press of the control pedal --- src/audioinputenginemidi.cc | 55 +++++++++++---------------------------------- src/midimapper.cc | 26 ++++++++++++++++++--- src/midimapper.h | 9 ++++++++ 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/audioinputenginemidi.cc b/src/audioinputenginemidi.cc index 820273c..564a5d6 100644 --- a/src/audioinputenginemidi.cc +++ b/src/audioinputenginemidi.cc @@ -108,10 +108,6 @@ static const std::uint8_t TypeMask = 0xF0; // See: // https://www.midi.org/specifications-old/item/table-1-summary-of-midi-message - -// TODO better implementation: use member variable for controller value, set MIDI key on command line -int hihat_midi_key = 26; - void AudioInputEngineMidi::processNote(const std::uint8_t* midi_buffer, std::size_t midi_buffer_length, std::size_t offset, @@ -142,6 +138,8 @@ void AudioInputEngineMidi::processNote(const std::uint8_t* midi_buffer, /* +// TODO better implementation: use member variable for controller value, set MIDI key on command line +int hihat_midi_key = 26; // quick hack, add 1000000 to offset to transport hi-hat controller value auto instrument_idx1 = mmap.lookup(hihat_midi_key); if(instrument_idx == instrument_idx1) @@ -186,45 +184,18 @@ if(instrument_idx == instrument_idx1) if(controller_number == 4) // usually, controller 4 is the hi-hat controller { -/* - // in case the hi-hat was just closed, choke current hi-hat samples - if(controller4_value < 100 && value > 100) - { -// TODO -// quick hack: if hi-hat control pedal is down, choke hi-hat instrument -auto instrument_idx = mmap.lookup(hihat_midi_key); -if(instrument_idx != -1) -{ - events.push_back({ EventType::Choke, (std::size_t)instrument_idx, - offset, .0f, .0f }); -} - } -*/ - - // Store value for use in next NoteOn event. - controller4_value = value; - - -// TODO here, we only apply the choke on controller4 == 0 but we have to apply it to all possible hi-hat instruments - -// quick hack: if hi-hat control pedal is down, choke hi-hat instrument -auto instrument_idx = mmap.lookup(hihat_midi_key, 0); -if(value > 100 && instrument_idx != -1) // quick hack: hard-coded value -{ - -/* -// TEST to force hihat group choke -> does not work -events.push_back({ EventType::OnSet, (std::size_t)instrument_idx, - offset, .0f, .0f }); -*/ - - events.push_back({ EventType::Choke, (std::size_t)instrument_idx, - offset, .0f, .0f }); - -//printf("choke on instrument index: %d\n", instrument_idx); -} - + // in case the hi-hat was just closed, choke current hi-hat samples + if(controller4_value < mmap.getMaxControlthresh() && value >= mmap.getMaxControlthresh()) + { + for(auto instrument_idx : mmap.getInstWithControlthresh()) + { + events.push_back({ EventType::Choke, (std::size_t)instrument_idx, + offset, .0f, .0f }); + } + } + // Store value for use in next NoteOn event. + controller4_value = value; } } break; diff --git a/src/midimapper.cc b/src/midimapper.cc index 62b9d87..1f75461 100644 --- a/src/midimapper.cc +++ b/src/midimapper.cc @@ -47,13 +47,13 @@ int MidiMapper::lookup(int note, int controller) // find instrument where controller is above threshold with smallest distance to threshold int diff = 10000; std::string instr = controlthreshmap[note].begin()->first; - for(auto& c : controlthreshmap[note]) + for(auto& control_thresh : controlthreshmap[note]) { - int cur_diff = controller - c.second; + int cur_diff = controller - control_thresh.second; if(cur_diff >= 0 && cur_diff < diff) { diff = cur_diff; - instr = c.first; + instr = control_thresh.first; } } instrmap_it = instrmap.find(instr); @@ -69,6 +69,26 @@ void MidiMapper::swap(instrmap_t& instrmap, midimap_t& midimap, controlthreshmap std::swap(this->instrmap, instrmap); std::swap(this->midimap, midimap); std::swap(this->controlthreshmap, controlthreshmap); + + // find instruments which define a control threshold and store it + for(auto& control_thresh : this->controlthreshmap) + { + for(auto& instr : control_thresh.second) + { + auto instrmap_it = this->instrmap.find(instr.first); + if(instrmap_it != this->instrmap.end()) + { + instwithcontrolthresh.push_back(instrmap_it->second); + } + maxcontrolthresh = std::max(maxcontrolthresh, instr.second); + } + } + + // in case no controller threshold is defined, use fix definition + if(maxcontrolthresh == 0) + { + maxcontrolthresh = 100; + } } const midimap_t& MidiMapper::getMap() diff --git a/src/midimapper.h b/src/midimapper.h index 5c81fd0..adb5777 100644 --- a/src/midimapper.h +++ b/src/midimapper.h @@ -29,6 +29,7 @@ #include #include #include +#include typedef std::map midimap_t; typedef std::map instrmap_t; @@ -41,6 +42,12 @@ public: //! \returns -1 if not found or the note index. int lookup(int note, int controller = -1); + //! Get all instruments with controller thresholds defined. + std::vector& getInstWithControlthresh() { return instwithcontrolthresh; } + + //! Get the maximum configured control threshold + int getMaxControlthresh() { return maxcontrolthresh; } + //! Set new map sets. void swap(instrmap_t& instrmap, midimap_t& midimap, controlthreshmap_t& controlthreshmap); @@ -50,6 +57,8 @@ private: instrmap_t instrmap; midimap_t midimap; controlthreshmap_t controlthreshmap; + std::vector instwithcontrolthresh; + int maxcontrolthresh{0}; std::mutex mutex; }; -- cgit v1.2.3