From 474a3c5f699c9f31afe98e5cdd26c489e29f7241 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 27 Oct 2019 13:54:47 +0100 Subject: Virtual-keyboard: allow octave switches while hand-pedaling --- gtk2_ardour/pianokeyboard.cc | 62 +++++++++++++++++++++++--------------------- gtk2_ardour/pianokeyboard.h | 1 + 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/gtk2_ardour/pianokeyboard.cc b/gtk2_ardour/pianokeyboard.cc index 96f1569d5c..d2bb0636af 100644 --- a/gtk2_ardour/pianokeyboard.cc +++ b/gtk2_ardour/pianokeyboard.cc @@ -293,7 +293,7 @@ APianoKeyboard::stop_sustained_notes () int APianoKeyboard::key_binding (const char* key) const { - if (_key_bindings.find (key) != _key_bindings.end ()) { + if (key && _key_bindings.find (key) != _key_bindings.end ()) { return _key_bindings.at (key); } return -1; @@ -520,14 +520,9 @@ APianoKeyboard::bind_keys_basic_qwertz () bind_key ("apostrophe", 29); } - -bool -APianoKeyboard::on_key_press_event (GdkEventKey* event) +static char* +get_keycode (GdkEventKey* event) { - int note; - char* key; - guint keyval; - GdkKeymapKey kk; /* We're not using event->keyval, because we need keyval with level set to 0. @@ -536,45 +531,56 @@ APianoKeyboard::on_key_press_event (GdkEventKey* event) kk.level = 0; kk.group = 0; - keyval = gdk_keymap_lookup_key (NULL, &kk); - - key = gdk_keyval_name (gdk_keyval_to_lower (keyval)); - - if (key == NULL) { - return false; - } + guint keyval = gdk_keymap_lookup_key (NULL, &kk); + return gdk_keyval_name (gdk_keyval_to_lower (keyval)); +} - note = key_binding (key); +bool +APianoKeyboard::on_key_press_event (GdkEventKey* event) +{ + char* key = get_keycode (event); + int note = key_binding (key); if (note < 0) { return false; } if (note == 128) { - if (event->type == GDK_KEY_RELEASE) { - Rest (); /* EMIT SIGNAL */ - return true; - } + /* Rest is used on release */ return false; } note += _octave * 12; + assert (key); assert (note >= 0); assert (note < NNOTES); - if (event->type == GDK_KEY_PRESS) { - press_key (note, _key_velocity); - } else if (event->type == GDK_KEY_RELEASE) { - release_key (note); - } + _note_stack[key] = note; + + press_key (note, _key_velocity); + return true; } bool APianoKeyboard::on_key_release_event (GdkEventKey* event) { - return on_key_press_event (event); + char* key = get_keycode (event); + + if (key_binding (key) == 128) { + Rest (); /* EMIT SIGNAL */ + return true; + } + + if (_note_stack.find (key) == _note_stack.end ()) { + return key_binding (key) != -1; + } + + release_key (_note_stack.at(key)); + _note_stack.erase (key); + + return true; } int @@ -946,8 +952,6 @@ APianoKeyboard::set_note_off (int note) void APianoKeyboard::set_octave (int octave) { - stop_unsustained_notes (); - if (octave < -1) { octave = -1; } else if (octave > 7) { @@ -961,8 +965,6 @@ APianoKeyboard::set_octave (int octave) void APianoKeyboard::set_octave_range (int octave_range) { - stop_unsustained_notes (); - if (octave_range < 2) { octave_range = 2; } diff --git a/gtk2_ardour/pianokeyboard.h b/gtk2_ardour/pianokeyboard.h index 7380cb5ec1..d4435e56b2 100644 --- a/gtk2_ardour/pianokeyboard.h +++ b/gtk2_ardour/pianokeyboard.h @@ -141,6 +141,7 @@ private: std::map _key_bindings; /**< Table used to translate from PC keyboard character to MIDI note number. */ std::map _note_bindings; /**< Table to translate from MIDI note number to PC keyboard character. */ + std::map _note_stack; /* these are only valid during expose/draw */ PangoFontDescription* _font_cue; -- cgit v1.2.3