From ae554501554dfbe379cb9d73ec3f480333a16a30 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+LostRobotMusic@users.noreply.github.com> Date: Sat, 5 Nov 2022 15:42:56 -0700 Subject: [PATCH] Make shifting notes by octaves respect microtuning (#6545) --- include/Microtuner.h | 1 + src/core/Microtuner.cpp | 13 ++++++++++++- src/gui/editors/PianoRoll.cpp | 15 ++++++++++++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/Microtuner.h b/include/Microtuner.h index 934739ff5..dff8f5773 100644 --- a/include/Microtuner.h +++ b/include/Microtuner.h @@ -54,6 +54,7 @@ public: float baseFreq() const; float keyToFreq(int key, int userBaseNote) const; + int octaveSize() const; QString nodeName() const override {return "microtuner";} void saveSettings(QDomDocument & document, QDomElement &element) override; diff --git a/src/core/Microtuner.cpp b/src/core/Microtuner.cpp index f8de21267..9c5ab871b 100644 --- a/src/core/Microtuner.cpp +++ b/src/core/Microtuner.cpp @@ -108,6 +108,17 @@ float Microtuner::keyToFreq(int key, int userBaseNote) const return middleFreq * intervals[scaleDegree].getRatio() * pow(octaveRatio, keymapOctave + scaleOctave); } +int Microtuner::octaveSize() const +{ + const int keymapSize = Engine::getSong()->getKeymap(currentKeymap())->getSize(); + if (keymapSize > 0) + { + return keymapSize; + } + + // Determine octave size from the scale if the keymap isn't in use. + return Engine::getSong()->getScale(currentScale())->getIntervals().size() - 1; +} /** * \brief Update scale name displayed in the microtuner scale list. @@ -170,4 +181,4 @@ void Microtuner::loadSettings(const QDomElement &element) } -} // namespace lmms \ No newline at end of file +} // namespace lmms diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index bc1245615..92c5ba72a 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1310,16 +1310,25 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke) int direction = (ke->key() == Qt::Key_Up ? +1 : -1); if( ( ke->modifiers() & Qt::ControlModifier ) && m_action == ActionNone ) { - // shift selection up an octave + // shift selection by one octave // if nothing selected, shift _everything_ if (hasValidMidiClip()) { - shiftSemiTone( 12 * direction ); + // An octave could potentially be greater or less than twelve semitones if the microtuner is in use. + const auto microtuner = m_midiClip->instrumentTrack()->microtuner(); + if (microtuner->enabled()) + { + shiftSemiTone(microtuner->octaveSize() * direction); + } + else + { + shiftSemiTone(12 * direction); + } } } else if((ke->modifiers() & Qt::ShiftModifier) && m_action == ActionNone) { - // Move selected notes up by one semitone + // Move selected notes by one semitone if (hasValidMidiClip()) { shiftSemiTone( 1 * direction );