Push2: Add UI for changing the vertical interval
This commit is contained in:
parent
d5ca05edff
commit
e93b7e2507
|
@ -78,6 +78,23 @@ using namespace Gtkmm2ext;
|
|||
#define ABLETON 0x2982
|
||||
#define PUSH2 0x1967
|
||||
|
||||
static int
|
||||
row_interval_semitones (const Push2::RowInterval row_interval)
|
||||
{
|
||||
switch (row_interval) {
|
||||
case Push2::Third:
|
||||
return 4;
|
||||
case Push2::Fourth:
|
||||
return 5;
|
||||
case Push2::Fifth:
|
||||
return 7;
|
||||
case Push2::Sequential:
|
||||
return 8;
|
||||
}
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
Push2::Push2 (ARDOUR::Session& s)
|
||||
: ControlProtocol (s, std::string (X_("Ableton Push 2")))
|
||||
, AbstractUI<Push2Request> (name())
|
||||
|
@ -90,6 +107,7 @@ Push2::Push2 (ARDOUR::Session& s)
|
|||
, _connection_state (ConnectionState (0))
|
||||
, _gui (0)
|
||||
, _mode (MusicalMode::IonianMajor)
|
||||
, _row_interval (Fourth)
|
||||
, _scale_root (0)
|
||||
, _root_octave (3)
|
||||
, _in_key (true)
|
||||
|
@ -196,7 +214,7 @@ Push2::begin_using_device ()
|
|||
|
||||
init_buttons (true);
|
||||
init_touch_strip ();
|
||||
set_pad_scale (_scale_root, _root_octave, _mode, _in_key);
|
||||
set_pad_scale (_scale_root, _root_octave, _mode, _row_interval, _in_key);
|
||||
splash ();
|
||||
|
||||
/* catch current selection, if any so that we can wire up the pads if appropriate */
|
||||
|
@ -1306,7 +1324,7 @@ Push2::update_selection_color ()
|
|||
void
|
||||
Push2::reset_pad_colors ()
|
||||
{
|
||||
set_pad_scale (_scale_root, _root_octave, _mode, _in_key);
|
||||
set_pad_scale (_scale_root, _root_octave, _mode, _row_interval, _in_key);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1493,16 +1511,18 @@ void
|
|||
Push2::set_pad_scale (const int scale_root,
|
||||
const int octave,
|
||||
const MusicalMode::Type mode,
|
||||
const RowInterval row_interval,
|
||||
const bool inkey)
|
||||
{
|
||||
// Clear the pad map and call the appropriate method to set them up again
|
||||
|
||||
_fn_pad_map.clear ();
|
||||
|
||||
const int vertical_semitones = row_interval_semitones(row_interval);
|
||||
if (inkey) {
|
||||
set_pad_scale_in_key(scale_root, octave, mode, 5);
|
||||
set_pad_scale_in_key(scale_root, octave, mode, vertical_semitones);
|
||||
} else {
|
||||
set_pad_scale_chromatic(scale_root, octave, mode, 5);
|
||||
set_pad_scale_chromatic(scale_root, octave, mode, vertical_semitones);
|
||||
}
|
||||
|
||||
// Store state
|
||||
|
@ -1525,6 +1545,10 @@ Push2::set_pad_scale (const int scale_root,
|
|||
_mode = mode;
|
||||
changed = true;
|
||||
}
|
||||
if (_row_interval != row_interval) {
|
||||
_row_interval = row_interval;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
ScaleChange (); /* EMIT SIGNAL */
|
||||
|
@ -1536,7 +1560,7 @@ Push2::set_percussive_mode (bool yn)
|
|||
{
|
||||
if (!yn) {
|
||||
cerr << "back to scale\n";
|
||||
set_pad_scale (_scale_root, _root_octave, _mode, _in_key);
|
||||
set_pad_scale (_scale_root, _root_octave, _mode, _row_interval, _in_key);
|
||||
_percussion = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -325,6 +325,19 @@ class Push2 : public ARDOUR::ControlProtocol
|
|||
|
||||
void update_selection_color ();
|
||||
|
||||
/** Interval between vertically adjacent note pads ("layout").
|
||||
*
|
||||
* The comments describe the ideal interval that is used in chromatic mode.
|
||||
* For in-scale mode, they may be slightly adjusted, hence the more general
|
||||
* enumerator names.
|
||||
*/
|
||||
enum RowInterval {
|
||||
Third, /// Major third or 4 semitones
|
||||
Fourth, /// Perfect fourth or 5 semitones
|
||||
Fifth, /// Perfect fifth or 7 semitones
|
||||
Sequential, /// Sequential from the last row, or 8 semitones
|
||||
};
|
||||
|
||||
/// "Kind" of pad that plays a note
|
||||
enum PadNoteKind { RootNote, InScaleNote, OutOfScaleNote };
|
||||
|
||||
|
@ -378,10 +391,16 @@ class Push2 : public ARDOUR::ControlProtocol
|
|||
MusicalMode::Type mode,
|
||||
int vertical_semitones);
|
||||
|
||||
void set_pad_scale (int root, int octave, MusicalMode::Type mode, bool inkey);
|
||||
void set_pad_scale (int root,
|
||||
int octave,
|
||||
MusicalMode::Type mode,
|
||||
RowInterval row_interval,
|
||||
bool inkey);
|
||||
|
||||
PBD::Signal0<void> ScaleChange;
|
||||
|
||||
MusicalMode::Type mode() const { return _mode; }
|
||||
RowInterval row_interval() const { return _row_interval; }
|
||||
int scale_root() const { return _scale_root; }
|
||||
int root_octave() const { return _root_octave; }
|
||||
bool in_key() const { return _in_key; }
|
||||
|
@ -621,6 +640,7 @@ class Push2 : public ARDOUR::ControlProtocol
|
|||
void stripable_selection_changed ();
|
||||
|
||||
MusicalMode::Type _mode;
|
||||
RowInterval _row_interval;
|
||||
int _scale_root;
|
||||
int _root_octave;
|
||||
bool _in_key;
|
||||
|
|
|
@ -42,6 +42,23 @@ using namespace ArdourCanvas;
|
|||
|
||||
static double unselected_root_alpha = 0.5;
|
||||
|
||||
static const char*
|
||||
row_interval_string (const Push2::RowInterval row_interval)
|
||||
{
|
||||
switch (row_interval) {
|
||||
case Push2::Third:
|
||||
return _("3rd \u2191");
|
||||
case Push2::Fourth:
|
||||
return _("4th \u2191");
|
||||
case Push2::Fifth:
|
||||
return _("5th \u2191");
|
||||
case Push2::Sequential:
|
||||
return _("Sequential \u21C9");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
ScaleLayout::ScaleLayout (Push2& p, Session & s, std::string const & name)
|
||||
: Push2Layout (p, s, name)
|
||||
, _last_vpot (-1)
|
||||
|
@ -62,7 +79,7 @@ ScaleLayout::ScaleLayout (Push2& p, Session & s, std::string const & name)
|
|||
|
||||
_close_text = new Text (this);
|
||||
_close_text->set_font_description (fd);
|
||||
_close_text->set_position (Duple (25, 5));
|
||||
_close_text->set_position (Duple (10, 5));
|
||||
_close_text->set_color (_p2.get_color (Push2::LightBackground));
|
||||
_close_text->set (_("Close"));
|
||||
|
||||
|
@ -84,6 +101,12 @@ ScaleLayout::ScaleLayout (Push2& p, Session & s, std::string const & name)
|
|||
_chromatic_text->set_color (_p2.get_color (Push2::LightBackground));
|
||||
_chromatic_text->set (_("Chromatic"));
|
||||
|
||||
_row_interval_text = new Text (this);
|
||||
_row_interval_text->set_font_description (fd);
|
||||
_row_interval_text->set_position (Duple (10, 70));
|
||||
_row_interval_text->set_color (_p2.get_color (Push2::LightBackground));
|
||||
_row_interval_text->set (row_interval_string (_p2.row_interval ()));
|
||||
|
||||
for (int n = 0; n < 8; ++n) {
|
||||
|
||||
/* text labels for root notes etc.*/
|
||||
|
@ -215,14 +238,22 @@ ScaleLayout::button_upper (uint32_t n)
|
|||
return;
|
||||
}
|
||||
|
||||
_p2.set_pad_scale (root, _p2.root_octave(), _p2.mode(), _p2.in_key());
|
||||
_p2.set_pad_scale (root,
|
||||
_p2.root_octave (),
|
||||
_p2.mode (),
|
||||
_p2.row_interval (),
|
||||
_p2.in_key ());
|
||||
}
|
||||
|
||||
void
|
||||
ScaleLayout::button_lower (uint32_t n)
|
||||
{
|
||||
if (n == 0) {
|
||||
_p2.set_pad_scale (_p2.scale_root(), _p2.root_octave(), _p2.mode(), !_p2.in_key());
|
||||
_p2.set_pad_scale (_p2.scale_root (),
|
||||
_p2.root_octave (),
|
||||
_p2.mode (),
|
||||
_p2.row_interval (),
|
||||
!_p2.in_key ());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -258,7 +289,11 @@ ScaleLayout::button_lower (uint32_t n)
|
|||
return;
|
||||
}
|
||||
|
||||
_p2.set_pad_scale (root, _p2.root_octave(), _p2.mode(), _p2.in_key());
|
||||
_p2.set_pad_scale (root,
|
||||
_p2.root_octave (),
|
||||
_p2.mode (),
|
||||
_p2.row_interval (),
|
||||
_p2.in_key ());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -328,22 +363,18 @@ ScaleLayout::show ()
|
|||
void
|
||||
ScaleLayout::strip_vpot (int n, int delta)
|
||||
{
|
||||
/* menu starts under the 2nd-from-left vpot */
|
||||
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_last_vpot != n) {
|
||||
uint32_t effective_column = n - 1;
|
||||
uint32_t active = _scale_menu->active ();
|
||||
if (n > 0) {
|
||||
uint32_t effective_column = n - 1;
|
||||
uint32_t active = _scale_menu->active ();
|
||||
|
||||
if (active / _scale_menu->rows() != effective_column) {
|
||||
/* knob turned is different than the current active column.
|
||||
Just change that.
|
||||
*/
|
||||
_scale_menu->set_active (effective_column * _scale_menu->rows()); /* top entry of that column */
|
||||
return;
|
||||
if (active / _scale_menu->rows() != effective_column) {
|
||||
/* knob turned is different than the current active column.
|
||||
Just change that.
|
||||
*/
|
||||
_scale_menu->set_active (effective_column * _scale_menu->rows()); /* top entry of that column */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* new vpot, reset delta cnt */
|
||||
|
@ -365,10 +396,30 @@ ScaleLayout::strip_vpot (int n, int delta)
|
|||
|
||||
const int vpot_slowdown_factor = 4;
|
||||
|
||||
if ((_vpot_delta_cnt < 0) && (_vpot_delta_cnt % vpot_slowdown_factor == 0)) {
|
||||
_scale_menu->scroll (Push2Menu::DirectionUp);
|
||||
} else if (_vpot_delta_cnt % vpot_slowdown_factor == 0) {
|
||||
_scale_menu->scroll (Push2Menu::DirectionDown);
|
||||
const bool moved_enough = _vpot_delta_cnt % vpot_slowdown_factor == 0;
|
||||
if (moved_enough) {
|
||||
if (n == 0) {
|
||||
Push2::RowInterval row_interval = _p2.row_interval();
|
||||
if (_vpot_delta_cnt < 0 && row_interval > Push2::Third) {
|
||||
row_interval = (Push2::RowInterval)(row_interval - 1);
|
||||
} else if (_vpot_delta_cnt > 0 && row_interval < Push2::Sequential) {
|
||||
row_interval = (Push2::RowInterval)(row_interval + 1);
|
||||
}
|
||||
|
||||
_p2.set_pad_scale (_p2.scale_root (),
|
||||
_p2.root_octave (),
|
||||
_p2.mode (),
|
||||
row_interval,
|
||||
_p2.in_key ());
|
||||
|
||||
_row_interval_text->set(row_interval_string(row_interval));
|
||||
} else {
|
||||
if (_vpot_delta_cnt < 0) {
|
||||
_scale_menu->scroll (Push2Menu::DirectionUp);
|
||||
} else {
|
||||
_scale_menu->scroll (Push2Menu::DirectionDown);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -584,7 +635,7 @@ void
|
|||
ScaleLayout::mode_changed ()
|
||||
{
|
||||
MusicalMode::Type m = (MusicalMode::Type) _scale_menu->active();
|
||||
_p2.set_pad_scale (_p2.scale_root(), _p2.root_octave(), m, _p2.in_key());
|
||||
_p2.set_pad_scale (_p2.scale_root(), _p2.root_octave(), m, _p2.row_interval(), _p2.in_key());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -59,6 +59,7 @@ class ScaleLayout : public Push2Layout
|
|||
ArdourCanvas::Text* _right_scroll_text;
|
||||
ArdourCanvas::Text* _inkey_text;
|
||||
ArdourCanvas::Text* _chromatic_text;
|
||||
ArdourCanvas::Text* _row_interval_text;
|
||||
ArdourCanvas::Text* _close_text;
|
||||
Push2Menu* _scale_menu;
|
||||
int _last_vpot;
|
||||
|
|
Loading…
Reference in New Issue
Block a user