mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-18 12:46:32 +01:00
Push2: Add "fixed" and "rooted" note grid option
This commit is contained in:
parent
ecd1a9660b
commit
e4e874bed0
4 changed files with 89 additions and 10 deletions
|
|
@ -214,7 +214,7 @@ Push2::begin_using_device ()
|
||||||
|
|
||||||
init_buttons (true);
|
init_buttons (true);
|
||||||
init_touch_strip ();
|
init_touch_strip ();
|
||||||
set_pad_scale (_scale_root, _root_octave, _mode, _row_interval, _in_key);
|
set_pad_scale (_scale_root, _root_octave, _mode, _note_grid_origin, _row_interval, _in_key);
|
||||||
splash ();
|
splash ();
|
||||||
|
|
||||||
/* catch current selection, if any so that we can wire up the pads if appropriate */
|
/* catch current selection, if any so that we can wire up the pads if appropriate */
|
||||||
|
|
@ -1318,7 +1318,7 @@ Push2::update_selection_color ()
|
||||||
void
|
void
|
||||||
Push2::reset_pad_colors ()
|
Push2::reset_pad_colors ()
|
||||||
{
|
{
|
||||||
set_pad_scale (_scale_root, _root_octave, _mode, _row_interval, _in_key);
|
set_pad_scale (_scale_root, _root_octave, _mode, _note_grid_origin, _row_interval, _in_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1437,13 +1437,17 @@ void
|
||||||
Push2::set_pad_scale_in_key (const int scale_root,
|
Push2::set_pad_scale_in_key (const int scale_root,
|
||||||
const int octave,
|
const int octave,
|
||||||
const MusicalMode::Type mode,
|
const MusicalMode::Type mode,
|
||||||
|
const NoteGridOrigin origin,
|
||||||
const int ideal_vertical_semitones)
|
const int ideal_vertical_semitones)
|
||||||
{
|
{
|
||||||
const std::vector<int> notes = mode_notes_vector (scale_root, octave, mode);
|
const std::vector<int> notes = mode_notes_vector (scale_root, octave, mode);
|
||||||
|
|
||||||
|
const int ideal_first_note = origin == Fixed ? 36 : scale_root + (12 * octave);
|
||||||
|
|
||||||
for (int row = 0; row < 8; ++row) {
|
for (int row = 0; row < 8; ++row) {
|
||||||
// The ideal leftmost note in a row is based only on the "tuning"
|
// The ideal leftmost note in a row is based only on the "tuning"
|
||||||
const int ideal_leftmost_note = 36 + (ideal_vertical_semitones * row);
|
const int ideal_leftmost_note =
|
||||||
|
ideal_first_note + (ideal_vertical_semitones * row);
|
||||||
|
|
||||||
// If that's in the scale, use it, otherwise use the closest higher note
|
// If that's in the scale, use it, otherwise use the closest higher note
|
||||||
std::vector<int>::const_iterator n =
|
std::vector<int>::const_iterator n =
|
||||||
|
|
@ -1472,13 +1476,16 @@ void
|
||||||
Push2::set_pad_scale_chromatic (const int scale_root,
|
Push2::set_pad_scale_chromatic (const int scale_root,
|
||||||
const int octave,
|
const int octave,
|
||||||
const MusicalMode::Type mode,
|
const MusicalMode::Type mode,
|
||||||
|
const NoteGridOrigin origin,
|
||||||
const int vertical_semitones)
|
const int vertical_semitones)
|
||||||
{
|
{
|
||||||
const std::bitset<128> notes = mode_notes_bitset (scale_root, octave, mode);
|
const std::bitset<128> notes = mode_notes_bitset (scale_root, octave, mode);
|
||||||
|
|
||||||
|
const int first_note = origin == Fixed ? 36 : scale_root + (12 * octave);
|
||||||
|
|
||||||
for (int row = 0; row < 8; ++row) {
|
for (int row = 0; row < 8; ++row) {
|
||||||
// The leftmost note in a row is just based only on the "tuning"
|
// The leftmost note in a row is just based only on the "tuning"
|
||||||
const int leftmost_note = 36 + (vertical_semitones * row);
|
const int leftmost_note = first_note + (vertical_semitones * row);
|
||||||
|
|
||||||
// Set up the the following columns in the row using the scale
|
// Set up the the following columns in the row using the scale
|
||||||
for (int col = 0; col < 8; ++col) {
|
for (int col = 0; col < 8; ++col) {
|
||||||
|
|
@ -1505,6 +1512,7 @@ void
|
||||||
Push2::set_pad_scale (const int scale_root,
|
Push2::set_pad_scale (const int scale_root,
|
||||||
const int octave,
|
const int octave,
|
||||||
const MusicalMode::Type mode,
|
const MusicalMode::Type mode,
|
||||||
|
const NoteGridOrigin origin,
|
||||||
const RowInterval row_interval,
|
const RowInterval row_interval,
|
||||||
const bool inkey)
|
const bool inkey)
|
||||||
{
|
{
|
||||||
|
|
@ -1514,9 +1522,9 @@ Push2::set_pad_scale (const int scale_root,
|
||||||
|
|
||||||
const int vertical_semitones = row_interval_semitones(row_interval);
|
const int vertical_semitones = row_interval_semitones(row_interval);
|
||||||
if (inkey) {
|
if (inkey) {
|
||||||
set_pad_scale_in_key(scale_root, octave, mode, vertical_semitones);
|
set_pad_scale_in_key(scale_root, octave, mode, origin, vertical_semitones);
|
||||||
} else {
|
} else {
|
||||||
set_pad_scale_chromatic(scale_root, octave, mode, vertical_semitones);
|
set_pad_scale_chromatic(scale_root, octave, mode, origin, vertical_semitones);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store state
|
// Store state
|
||||||
|
|
@ -1539,6 +1547,10 @@ Push2::set_pad_scale (const int scale_root,
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
if (_note_grid_origin != origin) {
|
||||||
|
_note_grid_origin = origin;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
if (_row_interval != row_interval) {
|
if (_row_interval != row_interval) {
|
||||||
_row_interval = row_interval;
|
_row_interval = row_interval;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
@ -1553,7 +1565,12 @@ void
|
||||||
Push2::set_percussive_mode (bool yn)
|
Push2::set_percussive_mode (bool yn)
|
||||||
{
|
{
|
||||||
if (!yn) {
|
if (!yn) {
|
||||||
set_pad_scale (_scale_root, _root_octave, _mode, _row_interval, _in_key);
|
set_pad_scale (_scale_root,
|
||||||
|
_root_octave,
|
||||||
|
_mode,
|
||||||
|
_note_grid_origin,
|
||||||
|
_row_interval,
|
||||||
|
_in_key);
|
||||||
_percussion = false;
|
_percussion = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -325,6 +325,17 @@ class Push2 : public ARDOUR::ControlProtocol
|
||||||
|
|
||||||
void update_selection_color ();
|
void update_selection_color ();
|
||||||
|
|
||||||
|
/** The "origin" or "root" of the note grid.
|
||||||
|
*
|
||||||
|
* This controls whether the grid is "fixed" in terms of the notes that it
|
||||||
|
* plays (so changing the scale is effectively just an overlay), or
|
||||||
|
* "rooted" so the root note of the scale is in the bottom left.
|
||||||
|
*/
|
||||||
|
enum NoteGridOrigin {
|
||||||
|
Fixed, ///< Bottom left pad is always C, or as close as possible
|
||||||
|
Rooted, ///< Bottom left pad is the scale root
|
||||||
|
};
|
||||||
|
|
||||||
/** Interval between vertically adjacent note pads ("layout").
|
/** Interval between vertically adjacent note pads ("layout").
|
||||||
*
|
*
|
||||||
* The comments describe the ideal interval that is used in chromatic mode.
|
* The comments describe the ideal interval that is used in chromatic mode.
|
||||||
|
|
@ -367,6 +378,7 @@ class Push2 : public ARDOUR::ControlProtocol
|
||||||
void set_pad_scale_in_key (int root,
|
void set_pad_scale_in_key (int root,
|
||||||
int octave,
|
int octave,
|
||||||
MusicalMode::Type mode,
|
MusicalMode::Type mode,
|
||||||
|
NoteGridOrigin origin,
|
||||||
int ideal_vertical_semitones);
|
int ideal_vertical_semitones);
|
||||||
|
|
||||||
/** Set a "chromatic" scale on the pads.
|
/** Set a "chromatic" scale on the pads.
|
||||||
|
|
@ -389,17 +401,20 @@ class Push2 : public ARDOUR::ControlProtocol
|
||||||
void set_pad_scale_chromatic (int root,
|
void set_pad_scale_chromatic (int root,
|
||||||
int octave,
|
int octave,
|
||||||
MusicalMode::Type mode,
|
MusicalMode::Type mode,
|
||||||
|
NoteGridOrigin origin,
|
||||||
int vertical_semitones);
|
int vertical_semitones);
|
||||||
|
|
||||||
void set_pad_scale (int root,
|
void set_pad_scale (int root,
|
||||||
int octave,
|
int octave,
|
||||||
MusicalMode::Type mode,
|
MusicalMode::Type mode,
|
||||||
|
NoteGridOrigin origin,
|
||||||
RowInterval row_interval,
|
RowInterval row_interval,
|
||||||
bool inkey);
|
bool inkey);
|
||||||
|
|
||||||
PBD::Signal0<void> ScaleChange;
|
PBD::Signal0<void> ScaleChange;
|
||||||
|
|
||||||
MusicalMode::Type mode() const { return _mode; }
|
MusicalMode::Type mode() const { return _mode; }
|
||||||
|
NoteGridOrigin note_grid_origin() { return _note_grid_origin; }
|
||||||
RowInterval row_interval() const { return _row_interval; }
|
RowInterval row_interval() const { return _row_interval; }
|
||||||
int scale_root() const { return _scale_root; }
|
int scale_root() const { return _scale_root; }
|
||||||
int root_octave() const { return _root_octave; }
|
int root_octave() const { return _root_octave; }
|
||||||
|
|
@ -640,6 +655,7 @@ class Push2 : public ARDOUR::ControlProtocol
|
||||||
void stripable_selection_changed ();
|
void stripable_selection_changed ();
|
||||||
|
|
||||||
MusicalMode::Type _mode;
|
MusicalMode::Type _mode;
|
||||||
|
NoteGridOrigin _note_grid_origin;
|
||||||
RowInterval _row_interval;
|
RowInterval _row_interval;
|
||||||
int _scale_root;
|
int _scale_root;
|
||||||
int _root_octave;
|
int _root_octave;
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,18 @@ ScaleLayout::ScaleLayout (Push2& p, Session & s, std::string const & name)
|
||||||
_chromatic_text->set_color (_p2.get_color (Push2::LightBackground));
|
_chromatic_text->set_color (_p2.get_color (Push2::LightBackground));
|
||||||
_chromatic_text->set (_("Chromatic"));
|
_chromatic_text->set (_("Chromatic"));
|
||||||
|
|
||||||
|
_fixed_text = new Text (this);
|
||||||
|
_fixed_text->set_font_description (fd2);
|
||||||
|
_fixed_text->set_position (Duple (10 + (7 * Push2Canvas::inter_button_spacing()), 140));
|
||||||
|
_fixed_text->set_color (_p2.get_color (Push2::LightBackground));
|
||||||
|
_fixed_text->set (_("Fixed"));
|
||||||
|
|
||||||
|
_rooted_text = new Text (this);
|
||||||
|
_rooted_text->set_font_description (fd2);
|
||||||
|
_rooted_text->set_position (Duple (45 + (7 * Push2Canvas::inter_button_spacing()), 140));
|
||||||
|
_rooted_text->set_color (_p2.get_color (Push2::LightBackground));
|
||||||
|
_rooted_text->set (_("Rooted"));
|
||||||
|
|
||||||
_row_interval_text = new Text (this);
|
_row_interval_text = new Text (this);
|
||||||
_row_interval_text->set_font_description (fd);
|
_row_interval_text->set_font_description (fd);
|
||||||
_row_interval_text->set_position (Duple (10, 70));
|
_row_interval_text->set_position (Duple (10, 70));
|
||||||
|
|
@ -241,6 +253,7 @@ ScaleLayout::button_upper (uint32_t n)
|
||||||
_p2.set_pad_scale (root,
|
_p2.set_pad_scale (root,
|
||||||
_p2.root_octave (),
|
_p2.root_octave (),
|
||||||
_p2.mode (),
|
_p2.mode (),
|
||||||
|
_p2.note_grid_origin (),
|
||||||
_p2.row_interval (),
|
_p2.row_interval (),
|
||||||
_p2.in_key ());
|
_p2.in_key ());
|
||||||
}
|
}
|
||||||
|
|
@ -252,12 +265,14 @@ ScaleLayout::button_lower (uint32_t n)
|
||||||
_p2.set_pad_scale (_p2.scale_root (),
|
_p2.set_pad_scale (_p2.scale_root (),
|
||||||
_p2.root_octave (),
|
_p2.root_octave (),
|
||||||
_p2.mode (),
|
_p2.mode (),
|
||||||
|
_p2.note_grid_origin (),
|
||||||
_p2.row_interval (),
|
_p2.row_interval (),
|
||||||
!_p2.in_key ());
|
!_p2.in_key ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int root = 0;
|
int root = _p2.scale_root();
|
||||||
|
Push2::NoteGridOrigin origin = _p2.note_grid_origin ();
|
||||||
|
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 1:
|
case 1:
|
||||||
|
|
@ -286,12 +301,14 @@ ScaleLayout::button_lower (uint32_t n)
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
/* fixed mode */
|
/* fixed mode */
|
||||||
return;
|
origin = (origin == Push2::Fixed) ? Push2::Rooted : Push2::Fixed;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_p2.set_pad_scale (root,
|
_p2.set_pad_scale (root,
|
||||||
_p2.root_octave (),
|
_p2.root_octave (),
|
||||||
_p2.mode (),
|
_p2.mode (),
|
||||||
|
origin,
|
||||||
_p2.row_interval (),
|
_p2.row_interval (),
|
||||||
_p2.in_key ());
|
_p2.in_key ());
|
||||||
}
|
}
|
||||||
|
|
@ -356,6 +373,7 @@ ScaleLayout::show ()
|
||||||
}
|
}
|
||||||
|
|
||||||
show_root_state ();
|
show_root_state ();
|
||||||
|
show_fixed_state ();
|
||||||
|
|
||||||
Container::show ();
|
Container::show ();
|
||||||
}
|
}
|
||||||
|
|
@ -409,6 +427,7 @@ ScaleLayout::strip_vpot (int n, int delta)
|
||||||
_p2.set_pad_scale (_p2.scale_root (),
|
_p2.set_pad_scale (_p2.scale_root (),
|
||||||
_p2.root_octave (),
|
_p2.root_octave (),
|
||||||
_p2.mode (),
|
_p2.mode (),
|
||||||
|
_p2.note_grid_origin (),
|
||||||
row_interval,
|
row_interval,
|
||||||
_p2.in_key ());
|
_p2.in_key ());
|
||||||
|
|
||||||
|
|
@ -629,13 +648,37 @@ ScaleLayout::show_root_state ()
|
||||||
}
|
}
|
||||||
|
|
||||||
_scale_menu->set_active ((uint32_t) _p2.mode ());
|
_scale_menu->set_active ((uint32_t) _p2.mode ());
|
||||||
|
|
||||||
|
show_fixed_state ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ScaleLayout::show_fixed_state ()
|
||||||
|
{
|
||||||
|
if (!parent()) {
|
||||||
|
/* don't do this stuff if we're not visible */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_p2.note_grid_origin() == Push2::Fixed) {
|
||||||
|
_rooted_text->set_color (change_alpha (_fixed_text->color(), unselected_root_alpha));
|
||||||
|
_fixed_text->set_color (change_alpha (_rooted_text->color(), 1.0));
|
||||||
|
} else {
|
||||||
|
_fixed_text->set_color (change_alpha (_fixed_text->color(), unselected_root_alpha));
|
||||||
|
_rooted_text->set_color (change_alpha (_rooted_text->color(), 1.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ScaleLayout::mode_changed ()
|
ScaleLayout::mode_changed ()
|
||||||
{
|
{
|
||||||
MusicalMode::Type m = (MusicalMode::Type) _scale_menu->active();
|
MusicalMode::Type m = (MusicalMode::Type) _scale_menu->active();
|
||||||
_p2.set_pad_scale (_p2.scale_root(), _p2.root_octave(), m, _p2.row_interval(), _p2.in_key());
|
_p2.set_pad_scale (_p2.scale_root (),
|
||||||
|
_p2.root_octave (),
|
||||||
|
m,
|
||||||
|
_p2.note_grid_origin (),
|
||||||
|
_p2.row_interval (),
|
||||||
|
_p2.in_key ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ class ScaleLayout : public Push2Layout
|
||||||
ArdourCanvas::Text* _right_scroll_text;
|
ArdourCanvas::Text* _right_scroll_text;
|
||||||
ArdourCanvas::Text* _inkey_text;
|
ArdourCanvas::Text* _inkey_text;
|
||||||
ArdourCanvas::Text* _chromatic_text;
|
ArdourCanvas::Text* _chromatic_text;
|
||||||
|
ArdourCanvas::Text* _fixed_text;
|
||||||
|
ArdourCanvas::Text* _rooted_text;
|
||||||
ArdourCanvas::Text* _row_interval_text;
|
ArdourCanvas::Text* _row_interval_text;
|
||||||
ArdourCanvas::Text* _close_text;
|
ArdourCanvas::Text* _close_text;
|
||||||
Push2Menu* _scale_menu;
|
Push2Menu* _scale_menu;
|
||||||
|
|
@ -72,6 +74,7 @@ class ScaleLayout : public Push2Layout
|
||||||
void mode_changed ();
|
void mode_changed ();
|
||||||
void menu_rearranged ();
|
void menu_rearranged ();
|
||||||
void show_root_state ();
|
void show_root_state ();
|
||||||
|
void show_fixed_state ();
|
||||||
void update_cursor_buttons ();
|
void update_cursor_buttons ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue