Add Pianokeyboard + Velocity Control to PC Dialog
This commit is contained in:
parent
a34764ec9f
commit
32bec8c8b1
@ -52,10 +52,11 @@ PatchChangeWidget::PatchChangeWidget (boost::shared_ptr<ARDOUR::Route> r)
|
|||||||
, _audition_enable (_("Audition on Change"), ArdourWidgets::ArdourButton::led_default_elements)
|
, _audition_enable (_("Audition on Change"), ArdourWidgets::ArdourButton::led_default_elements)
|
||||||
, _audition_start_spin (*manage (new Adjustment (48, 0, 127, 1, 16)))
|
, _audition_start_spin (*manage (new Adjustment (48, 0, 127, 1, 16)))
|
||||||
, _audition_end_spin (*manage (new Adjustment (60, 0, 127, 1, 16)))
|
, _audition_end_spin (*manage (new Adjustment (60, 0, 127, 1, 16)))
|
||||||
|
, _audition_velocity (*manage (new Adjustment (100, 1, 127, 1, 16)))
|
||||||
, _audition_note_on (false)
|
, _audition_note_on (false)
|
||||||
|
, _piano ((PianoKeyboard*)piano_keyboard_new())
|
||||||
|
, _pianomm (Glib::wrap((GtkWidget*)_piano))
|
||||||
{
|
{
|
||||||
assert (boost::dynamic_pointer_cast<MidiTrack> (r));
|
|
||||||
|
|
||||||
Box* box;
|
Box* box;
|
||||||
box = manage (new HBox ());
|
box = manage (new HBox ());
|
||||||
box->set_border_width (2);
|
box->set_border_width (2);
|
||||||
@ -74,18 +75,22 @@ PatchChangeWidget::PatchChangeWidget (boost::shared_ptr<ARDOUR::Route> r)
|
|||||||
_program_table.set_spacings (1);
|
_program_table.set_spacings (1);
|
||||||
pack_start (_program_table, true, true);
|
pack_start (_program_table, true, true);
|
||||||
|
|
||||||
box = manage (new HBox ());
|
if (boost::dynamic_pointer_cast<MidiTrack> (_route)) {
|
||||||
box->set_spacing (4);
|
box = manage (new HBox ());
|
||||||
box->pack_start (_audition_enable, false, false);
|
box->set_spacing (4);
|
||||||
box->pack_start (*manage (new Label (_("Start Note:"))), false, false);
|
box->pack_start (_audition_enable, false, false);
|
||||||
box->pack_start (_audition_start_spin, false, false);
|
box->pack_start (*manage (new Label (_("Start Note:"))), false, false);
|
||||||
box->pack_start (*manage (new Label (_("End Note:"))), false, false);
|
box->pack_start (_audition_start_spin, false, false);
|
||||||
box->pack_start (_audition_end_spin, false, false);
|
box->pack_start (*manage (new Label (_("End Note:"))), false, false);
|
||||||
|
box->pack_start (_audition_end_spin, false, false);
|
||||||
|
box->pack_start (*manage (new Label (_("Velocity:"))), false, false);
|
||||||
|
box->pack_start (_audition_velocity, false, false);
|
||||||
|
|
||||||
Box* box2 = manage (new HBox ());
|
Box* box2 = manage (new HBox ());
|
||||||
box2->pack_start (*box, true, false);
|
box2->pack_start (*box, true, false);
|
||||||
box2->set_border_width (2);
|
box2->set_border_width (2);
|
||||||
pack_start (*box2, false, false);
|
pack_start (*box2, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
for (uint8_t pgm = 0; pgm < 128; ++pgm) {
|
for (uint8_t pgm = 0; pgm < 128; ++pgm) {
|
||||||
_program_btn[pgm].set_text_ellipsize (Pango::ELLIPSIZE_END);
|
_program_btn[pgm].set_text_ellipsize (Pango::ELLIPSIZE_END);
|
||||||
@ -103,6 +108,14 @@ PatchChangeWidget::PatchChangeWidget (boost::shared_ptr<ARDOUR::Route> r)
|
|||||||
_channel_select.AddMenuElem (MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PatchChangeWidget::select_channel), chn)));
|
_channel_select.AddMenuElem (MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PatchChangeWidget::select_channel), chn)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (boost::dynamic_pointer_cast<MidiTrack> (_route)) {
|
||||||
|
piano_keyboard_set_monophonic (_piano, TRUE);
|
||||||
|
g_signal_connect (G_OBJECT (_piano), "note-on", G_CALLBACK (PatchChangeWidget::_note_on_event_handler), this);
|
||||||
|
g_signal_connect (G_OBJECT (_piano), "note-off", G_CALLBACK (PatchChangeWidget::_note_off_event_handler), this);
|
||||||
|
_pianomm->set_flags(Gtk::CAN_FOCUS);
|
||||||
|
pack_start (*_pianomm, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
_audition_start_spin.set_sensitive (false);
|
_audition_start_spin.set_sensitive (false);
|
||||||
_audition_end_spin.set_sensitive (false);
|
_audition_end_spin.set_sensitive (false);
|
||||||
|
|
||||||
@ -122,6 +135,7 @@ PatchChangeWidget::PatchChangeWidget (boost::shared_ptr<ARDOUR::Route> r)
|
|||||||
PatchChangeWidget::~PatchChangeWidget ()
|
PatchChangeWidget::~PatchChangeWidget ()
|
||||||
{
|
{
|
||||||
cancel_audition ();
|
cancel_audition ();
|
||||||
|
delete _pianomm;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -228,9 +242,6 @@ PatchChangeWidget::refill_program_list ()
|
|||||||
boost::replace_all (n, "_", " ");
|
boost::replace_all (n, "_", " ");
|
||||||
MIDI::Name::PatchPrimaryKey const& key = (*i)->patch_primary_key ();
|
MIDI::Name::PatchPrimaryKey const& key = (*i)->patch_primary_key ();
|
||||||
|
|
||||||
assert (key.program () < 128);
|
|
||||||
assert (key.bank () == bank (_channel));
|
|
||||||
|
|
||||||
const uint8_t pgm = key.program();
|
const uint8_t pgm = key.program();
|
||||||
_program_btn[pgm].set_text (n);
|
_program_btn[pgm].set_text (n);
|
||||||
set_tooltip (_program_btn[pgm], string_compose (_("%1 (Pgm-%2)"), n, (int)(pgm +1)));
|
set_tooltip (_program_btn[pgm], string_compose (_("%1 (Pgm-%2)"), n, (int)(pgm +1)));
|
||||||
@ -342,7 +353,8 @@ PatchChangeWidget::cancel_audition ()
|
|||||||
event[0] = (MIDI_CMD_NOTE_OFF | _channel);
|
event[0] = (MIDI_CMD_NOTE_OFF | _channel);
|
||||||
event[1] = _audition_note_num;
|
event[1] = _audition_note_num;
|
||||||
event[2] = 0;
|
event[2] = 0;
|
||||||
mt->write_immediate_event(3, event);
|
mt->write_immediate_event (3, event);
|
||||||
|
piano_keyboard_set_note_off (_piano, _audition_note_num);
|
||||||
}
|
}
|
||||||
_audition_note_on = false;
|
_audition_note_on = false;
|
||||||
}
|
}
|
||||||
@ -380,20 +392,61 @@ PatchChangeWidget::audition_next ()
|
|||||||
if (_audition_note_on) {
|
if (_audition_note_on) {
|
||||||
event[0] = (MIDI_CMD_NOTE_OFF | _channel);
|
event[0] = (MIDI_CMD_NOTE_OFF | _channel);
|
||||||
event[1] = _audition_note_num;
|
event[1] = _audition_note_num;
|
||||||
event[2] = 100;
|
event[2] = 0;
|
||||||
mt->write_immediate_event(3, event);
|
mt->write_immediate_event (3, event);
|
||||||
_audition_note_on = false;
|
_audition_note_on = false;
|
||||||
|
piano_keyboard_set_note_off (_piano, _audition_note_num);
|
||||||
return ++_audition_note_num <= _audition_end_spin.get_value_as_int() && _audition_enable.get_active ();
|
return ++_audition_note_num <= _audition_end_spin.get_value_as_int() && _audition_enable.get_active ();
|
||||||
} else {
|
} else {
|
||||||
event[0] = (MIDI_CMD_NOTE_ON | _channel);
|
event[0] = (MIDI_CMD_NOTE_ON | _channel);
|
||||||
event[1] = _audition_note_num;
|
event[1] = _audition_note_num;
|
||||||
event[2] = 100;
|
event[2] = _audition_velocity.get_value_as_int ();
|
||||||
mt->write_immediate_event(3, event);
|
mt->write_immediate_event (3, event);
|
||||||
_audition_note_on = true;
|
_audition_note_on = true;
|
||||||
|
piano_keyboard_set_note_on (_piano, _audition_note_num);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PatchChangeWidget::_note_on_event_handler(GtkWidget*, int note, gpointer arg)
|
||||||
|
{
|
||||||
|
((PatchChangeWidget*)arg)->note_on_event_handler(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PatchChangeWidget::_note_off_event_handler(GtkWidget*, int note, gpointer arg)
|
||||||
|
{
|
||||||
|
((PatchChangeWidget*)arg)->note_off_event_handler(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PatchChangeWidget::note_on_event_handler (int note)
|
||||||
|
{
|
||||||
|
cancel_audition ();
|
||||||
|
_pianomm->grab_focus ();
|
||||||
|
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (_route);
|
||||||
|
uint8_t event[3];
|
||||||
|
event[0] = (MIDI_CMD_NOTE_ON | _channel);
|
||||||
|
event[1] = note;
|
||||||
|
event[2] = _audition_velocity.get_value_as_int ();
|
||||||
|
mt->write_immediate_event (3, event);
|
||||||
|
_audition_note_on = true;
|
||||||
|
_audition_note_num = note;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PatchChangeWidget::note_off_event_handler (int note)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (_route);
|
||||||
|
uint8_t event[3];
|
||||||
|
event[0] = (MIDI_CMD_NOTE_OFF | _channel);
|
||||||
|
event[1] = note;
|
||||||
|
event[2] = 0;
|
||||||
|
mt->write_immediate_event (3, event);
|
||||||
|
_audition_note_on = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* ***** query info *****/
|
/* ***** query info *****/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "widgets/ardour_dropdown.h"
|
#include "widgets/ardour_dropdown.h"
|
||||||
|
|
||||||
#include "ardour_dialog.h"
|
#include "ardour_dialog.h"
|
||||||
|
#include "gtk_pianokeyboard.h"
|
||||||
|
|
||||||
class PatchChangeWidget : public Gtk::VBox
|
class PatchChangeWidget : public Gtk::VBox
|
||||||
{
|
{
|
||||||
@ -88,8 +89,17 @@ private:
|
|||||||
ArdourWidgets::ArdourButton _audition_enable;
|
ArdourWidgets::ArdourButton _audition_enable;
|
||||||
Gtk::SpinButton _audition_start_spin; // Consider a click-box w/note-names
|
Gtk::SpinButton _audition_start_spin; // Consider a click-box w/note-names
|
||||||
Gtk::SpinButton _audition_end_spin;
|
Gtk::SpinButton _audition_end_spin;
|
||||||
|
Gtk::SpinButton _audition_velocity;
|
||||||
uint8_t _audition_note_num;
|
uint8_t _audition_note_num;
|
||||||
bool _audition_note_on;
|
bool _audition_note_on;
|
||||||
|
|
||||||
|
PianoKeyboard* _piano;
|
||||||
|
Gtk::Widget* _pianomm;
|
||||||
|
|
||||||
|
static void _note_on_event_handler (GtkWidget*, int, gpointer);
|
||||||
|
static void _note_off_event_handler (GtkWidget*, int, gpointer);
|
||||||
|
void note_on_event_handler (int);
|
||||||
|
void note_off_event_handler (int);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PatchChangeGridDialog : public ArdourDialog
|
class PatchChangeGridDialog : public ArdourDialog
|
||||||
|
Loading…
Reference in New Issue
Block a user