Virtual-keyboard: add option to transpose
authorRobin Gareus <robin@gareus.org>
Mon, 21 Oct 2019 17:31:25 +0000 (19:31 +0200)
committerRobin Gareus <robin@gareus.org>
Mon, 21 Oct 2019 17:31:25 +0000 (19:31 +0200)
gtk2_ardour/virtual_keyboard_window.cc
gtk2_ardour/virtual_keyboard_window.h

index 66cc68eed9a45bbf91b21bd7a18a616aca500389..54a3456d26251c7591b22fc9078d6e52ebc23eaf 100644 (file)
@@ -39,6 +39,7 @@ using namespace ArdourWidgets;
 VirtualKeyboardWindow::VirtualKeyboardWindow ()
        : ArdourWindow (_("Virtual MIDI Keyboard"))
        , _piano_channel (*manage (new Adjustment (1, 1, 16, 1, 1)))
+       , _transpose_output (*manage (new Adjustment (0, -12, 12, 1, 1)))
        , _bank_msb (*manage (new Adjustment (0, 0, 127, 1, 16)))
        , _bank_lsb (*manage (new Adjustment (0, 0, 127, 1, 16)))
        , _patchpgm (*manage (new Adjustment (1, 1, 128, 1, 16)))
@@ -162,7 +163,8 @@ VirtualKeyboardWindow::VirtualKeyboardWindow ()
 
        const char* default_cc[VKBD_NCTRLS] = { "7", "8", "1", "11", "91", "92", "93", "94" };
 
-       for (int i = 0; i < VKBD_NCTRLS; ++i) {
+       int col = 3;
+       for (int i = 0; i < VKBD_NCTRLS; ++i, ++col) {
                _cc[i]      = boost::shared_ptr<VKBDControl> (new VKBDControl ("CC"));
                _cc_knob[i] = manage (new ArdourKnob (ArdourKnob::default_elements, ArdourKnob::Flags (0)));
                _cc_knob[i]->set_controllable (_cc[i]);
@@ -180,13 +182,18 @@ VirtualKeyboardWindow::VirtualKeyboardWindow ()
                }
                _cc_key[i].set_active (default_cc[i]);
 
-               tbl->attach (*_cc_knob[i], i + 3, i + 4, 0, 1, SHRINK, SHRINK, 4, 2);
-               tbl->attach (_cc_key[i],   i + 3, i + 4, 1, 2, SHRINK, SHRINK, 4, 2);
+               tbl->attach (*_cc_knob[i], col, col + 1, 0, 1, SHRINK, SHRINK, 4, 2);
+               tbl->attach (_cc_key[i],   col, col + 1, 1, 2, SHRINK, SHRINK, 4, 2);
 
                _cc[i]->ValueChanged.connect_same_thread (_cc_connections,
                                                          boost::bind (&VirtualKeyboardWindow::control_change_event_handler, this, i, _1));
        }
 
+       tbl->attach (*manage (new ArdourVSpacer), col, col + 1, 0, 2, SHRINK, FILL, 4, 0);
+       ++col;
+       tbl->attach (_transpose_output,                      col, col + 1, 0, 1, SHRINK, SHRINK, 4, 0);
+       tbl->attach (*manage (new Label (_("Transpose"))),   col, col + 1, 1, 2, SHRINK, SHRINK, 4, 0);
+
        /* main layout */
        Box* box1 = manage (new HBox ());
        box1->pack_start (*tbl, true, false);
@@ -271,6 +278,7 @@ VirtualKeyboardWindow::get_state ()
        node->set_property (X_("ShowNoteLabel"), _show_note_label.get_active ());
        node->set_property (X_("Layout"), _keyboard_layout.get_text ());
        node->set_property (X_("Channel"), _piano_channel.get_value_as_int ());
+       node->set_property (X_("Transpose"), _transpose_output.get_value_as_int ());
        node->set_property (X_("MinVelocity"), _piano_min_velocity.get_value_as_int ());
        node->set_property (X_("MaxVelocity"), _piano_max_velocity.get_value_as_int ());
        node->set_property (X_("KeyVelocity"), _piano_key_velocity.get_value_as_int ());
@@ -329,6 +337,9 @@ VirtualKeyboardWindow::set_state (const XMLNode& root)
        if (node->get_property (X_("Channel"), v)) {
                _piano_channel.set_value (v);
        }
+       if (node->get_property (X_("Transpose"), v)) {
+               _transpose_output.set_value (v);
+       }
        if (node->get_property (X_("MinVelocity"), v)) {
                _piano_min_velocity.set_value (v);
        }
@@ -531,6 +542,10 @@ VirtualKeyboardWindow::note_on_event_handler (int note, int velocity)
        if (!_session) {
                return;
        }
+       note += _transpose_output.get_value_as_int ();
+       if (note < 0 || note > 127) {
+               return;
+       }
        uint8_t channel = _piano_channel.get_value_as_int () - 1;
        uint8_t ev[3];
        ev[0] = MIDI_CMD_NOTE_ON | channel;
@@ -545,7 +560,10 @@ VirtualKeyboardWindow::note_off_event_handler (int note)
        if (!_session) {
                return;
        }
-
+       note += _transpose_output.get_value_as_int ();
+       if (note < 0 || note > 127) {
+               return;
+       }
        uint8_t channel = _piano_channel.get_value_as_int () - 1;
        uint8_t ev[3];
        ev[0] = MIDI_CMD_NOTE_OFF | channel;
index 0ed0a6841636176d1dcf4343a25f1d5988c2eb29..794b52a7f83fb589e1ae8067c263327518e3fff3 100644 (file)
@@ -130,6 +130,8 @@ private:
        Gtk::Widget*    _pianomm;
        Gtk::SpinButton _piano_channel;
 
+       Gtk::SpinButton _transpose_output;
+
        Gtk::SpinButton _bank_msb;
        Gtk::SpinButton _bank_lsb;
        Gtk::SpinButton _patchpgm;