diff --git a/TODO b/TODO index e0553815..dde8b6d9 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,9 @@ TO DO for Seq66 0.99.10 Chris Ahlstrom -2019-04-13 to 2023-10-07 +2019-04-13 to 2023-10-08 Misc: - - Issue #118 - Document and test mute groups. Issues: - performer: cliear_mute_groups(), reset_mute_groups(), and mutegroup_reset() all basically do the same things, except @@ -332,15 +331,14 @@ ISSUES: #117 Option to close pattern windows with esc key? - STATUS: Thinking... This can be done if (1) not playing; and - (2) not in Paint mode. + STATUS: Done, not yet official. #118 When enabling virtual ports, make those new ports enabled by default? Currently one has to tick the box to enable and enter the number of output and input ports, restart seq66, and then tick all the input port checkboxes in the list then restart seq66 again. - STATUS: At least make it an rc option. + STATUS: Done, not yet official. #119 Quantized Record Active does not work Having this button active has no effect; tried changing snap size to diff --git a/data/linux/qseq66.rc b/data/linux/qseq66.rc index 8f5a93f0..6232c6ab 100644 --- a/data/linux/qseq66.rc +++ b/data/linux/qseq66.rc @@ -47,6 +47,8 @@ MIDI Clocks and MIDI Inputs tabs. # Provides a flag and file-name for MIDI-control I/O settings. '""' means # no 'ctrl' file. If none, default keystrokes are used, with no MIDI control. +# Note that all configuration files are stored in the "home" configuration +# directory; any paths in the file-names are stripped. [midi-control-file] @@ -119,6 +121,7 @@ tempo-track = 0 [manual-ports] virtual-ports = false +auto-enable = false output-port-count = 8 input-port-count = 4 diff --git a/doc/latex/tex/menu.tex b/doc/latex/tex/menu.tex index 8a6448cb..c91387c7 100644 --- a/doc/latex/tex/menu.tex +++ b/doc/latex/tex/menu.tex @@ -6,7 +6,7 @@ % \library Documents % \author Chris Ahlstrom % \date 2015-08-31 -% \update 2023-10-07 +% \update 2023-10-08 % \version $Revision$ % \license $XPC_GPL_LICENSE$ % @@ -800,7 +800,7 @@ \subsubsection{Menu / Edit / Preferences} \texttt{-{}-reveal-ports} (\texttt{-r}) option. If you define these sections, they should match your hardware exactly, and your hardware should not change from session to - session. + session (or port-mapping should be enabled). If the "auto ALSA ports" option is turned on, via the \texttt{-a} or \texttt{-{}-auto-ports} option, then the input ports from the system are shown. @@ -829,21 +829,24 @@ \subsubsection{Menu / Edit / Preferences} \itempar{Input/Output Recording}{record!by channel} \index{input by channel} - \textbf{Record input into sequence according to channel} + \textbf{Record input into patterns by channel} causes MIDI input with multiple channels to be distributed to each sequence according to MIDI channel number. When disabled, the normal recording behavior dumps all data into the current sequence, regardless of channel. \itempar{Input/Output Virtual Ports}{ports!virtual} - \textbf{Use virtual (manual) I/O Ports} - This new option + \textbf{Use virtual (manual) I/O ports} + This option allows for configuration of the manual-ports option from within the user-interace. Once the option is enable A \textsl{reload session} (see \sectionref{subsec:concepts_reload_session}) is necessary for this option to take effect. + \itempar{Virtual Ports Auto-Enable}{ports!virtual auto-enable} + \textbf{Auto-enable virtual I/O ports} + \paragraph{Menu / Edit / Preferences / Keyboard (removed)} \label{paragraph:menu_edit_preferences_keyboard} diff --git a/libseq66/include/cfg/rcsettings.hpp b/libseq66/include/cfg/rcsettings.hpp index 5e5fec11..0e373a1d 100644 --- a/libseq66/include/cfg/rcsettings.hpp +++ b/libseq66/include/cfg/rcsettings.hpp @@ -28,7 +28,7 @@ * \library seq66 application * \author Chris Ahlstrom * \date 2015-09-22 - * \updates 2023-10-04 + * \updates 2023-10-07 * \license GNU GPLv2 or above * * This collection of variables describes the options of the application, @@ -278,6 +278,7 @@ class rcsettings final : public basesettings bool m_song_start_is_auto; /**< True if "auto" read from 'rc'. */ bool m_filter_by_channel; /**< Record only sequence channel data. */ bool m_manual_ports; /**< [manual-ports] setting. */ + bool m_manual_auto_enable; /**< [manual-port] auto-enable. */ int m_manual_port_count; /**< [manual-ports] outputjport count. */ int m_manual_in_port_count; /**< [manual-ports] inputjport count. */ bool m_reveal_ports; /**< [reveal-ports] setting. */ @@ -911,6 +912,11 @@ class rcsettings final : public basesettings return m_manual_ports; } + bool manual_auto_enable () const + { + return m_manual_auto_enable; + } + int manual_port_count () const { return m_manual_port_count; @@ -1341,6 +1347,11 @@ class rcsettings final : public basesettings m_manual_ports = flag; } + void manual_auto_enable (bool flag) + { + m_manual_auto_enable = flag; + } + void manual_port_count (int count) { if (count <= 0 || count > c_output_buss_max) diff --git a/libseq66/include/midi/midibase.hpp b/libseq66/include/midi/midibase.hpp index 0213acd5..6471f141 100644 --- a/libseq66/include/midi/midibase.hpp +++ b/libseq66/include/midi/midibase.hpp @@ -143,16 +143,16 @@ class midibase /** * This flag indicates if an input or output bus has been selected for - * action as an input device (such as a MIDI controller). It is turned on - * if the user selects the port in the Options / MIDI Input tab. + * action as an input device (such as a MIDI controller). It is turned + * on if the user selects the port in the Options / MIDI Input tab. */ bool m_io_active; /** - * Indicates if the port is unavailable. For example, when the - * Windows MIDI Mapper grabs the GS wave-table synthesizer. - * The port is not just disabled... it cannot be enabled. + * Indicates if the port is unavailable. For example, when the Windows + * MIDI Mapper grabs the GS wave-table synthesizer. The port is not + * just disabled... it cannot be enabled. */ bool m_unavailable; diff --git a/libseq66/src/cfg/rcfile.cpp b/libseq66/src/cfg/rcfile.cpp index 8fee94bc..2ecadbd7 100644 --- a/libseq66/src/cfg/rcfile.cpp +++ b/libseq66/src/cfg/rcfile.cpp @@ -25,7 +25,7 @@ * \library seq66 application * \author Chris Ahlstrom * \date 2018-11-23 - * \updates 2023-09-15 + * \updates 2023-10-08 * \license GNU GPLv2 or above * * The ~/.config/seq66.rc configuration file is fairly simple @@ -309,6 +309,8 @@ rcfile::parse () bool flag = get_boolean(file, tag, "virtual-ports"); rc_ref().manual_ports(flag); + flag = get_boolean(file, tag, "auto-enable"); + rc_ref().manual_auto_enable(flag); int count = get_integer(file, tag, "output-port-count"); rc_ref().manual_port_count(count); @@ -874,11 +876,12 @@ rcfile::write () file << "\n" "# Set to true to create virtual ALSA/JACK I/O ports and not auto-connect\n" "# to other clients. It allows up to 48 output or input ports (defaults to 8\n" -"# and 4). Set to false to auto-connect Seq66 to the existing ALSA/JACK MIDI\n" -"# ports.\n" +"# and 4). Keep it false to auto-connect Seq66 to real ALSA/JACK MIDI ports.\n" +"# Set 'auto-enable' to enable all virtual ports automatically.\n" "\n[manual-ports]\n\n" ; write_boolean(file, "virtual-ports", rc_ref().manual_ports()); + write_boolean(file, "auto-enable", rc_ref().manual_auto_enable()); write_integer(file, "output-port-count", rc_ref().manual_port_count()); write_integer(file, "input-port-count", rc_ref().manual_in_port_count()); @@ -887,8 +890,8 @@ rcfile::write () "# These MIDI ports are for input and control. JACK's view: these are\n" "# 'playback' devices. The first number is the bus, the second number is the\n" "# input status, disabled (0) or enabled (1). The item in quotes is the full\n" -"# input bus name.\n\n" -"[midi-input]\n\n" +"# input bus name. The type of port depends on the 'virtual-ports' setting.\n" +"\n[midi-input]\n\n" << std::setw(2) << int(inbuses) << " # number of MIDI input (or control) buses\n\n" ; @@ -942,11 +945,10 @@ rcfile::write () "#\n" "# With Clock Modulo, clocking doesn't begin until song position reaches the\n" "# start-modulo value [midi-clock-mod-ticks]. Ports that are unavailable\n" -"# (because another portapplication, e.g. Windows MIDI Mapper, has exclusive\n" -"# access to the device) are displayed ghosted.\n" -"\n" -"[midi-clock]\n" -"\n" +"# (because another port, e.g. Windows MIDI Mapper, has exclusive access to\n" +"# the device) are displayed ghosted. The type of port depends on the\n" +"# 'virtual-ports' setting.\n" +"\n[midi-clock]\n\n" << std::setw(2) << int(outbuses) << " # number of MIDI clocks (output/display buses)\n\n" ; diff --git a/libseq66/src/cfg/rcsettings.cpp b/libseq66/src/cfg/rcsettings.cpp index 5dd8eec6..ed616009 100644 --- a/libseq66/src/cfg/rcsettings.cpp +++ b/libseq66/src/cfg/rcsettings.cpp @@ -25,7 +25,7 @@ * \library seq66 application * \author Seq24 team; modifications by Chris Ahlstrom * \date 2015-09-22 - * \updates 2023-10-04 + * \updates 2023-10-08 * \license GNU GPLv2 or above * * Note that this module also sets the legacy global variables, so that @@ -98,6 +98,7 @@ rcsettings::rcsettings () : m_song_start_mode (sequence::playback::automatic), m_song_start_is_auto (true), m_manual_ports (false), + m_manual_auto_enable (false), m_manual_port_count (c_output_buss_default), m_manual_in_port_count (c_input_buss_default), m_reveal_ports (false), @@ -206,6 +207,7 @@ rcsettings::set_defaults () m_song_start_mode = sequence::playback::automatic; m_song_start_is_auto = true; m_manual_ports = false; + m_manual_auto_enable = false; m_manual_port_count = c_output_buss_default; m_manual_in_port_count = c_input_buss_default; m_reveal_ports = false; diff --git a/seq_qt5/forms/qseditoptions.ui b/seq_qt5/forms/qseditoptions.ui index e751599f..f90d4132 100644 --- a/seq_qt5/forms/qseditoptions.ui +++ b/seq_qt5/forms/qseditoptions.ui @@ -44,7 +44,7 @@ - 6 + 1 @@ -523,106 +523,6 @@ Each port number can be found by name-lookup. false - - - - 20 - 40 - 537 - 21 - - - - If checked, incoming data routes to the pattern -slot by channel number (0 to 15). - - - Record input into sequences according to channel - - - - - - 20 - 72 - 257 - 23 - - - - Use virtual (manual) I/O Ports - - - - - - 416 - 72 - 77 - 21 - - - - Inputs - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 284 - 72 - 77 - 21 - - - - Outputs - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 372 - 68 - 42 - 28 - - - - 8 - - - 2 - - - true - - - false - - - - - - 504 - 68 - 42 - 28 - - - - 4 - - - 2 - - @@ -641,6 +541,113 @@ slot by channel number (0 to 15). Input/Output Options + + + + 20 + 40 + 571 + 100 + + + + + + + Use virtual (manual) I/O ports + + + + + + + + 96 + 16777215 + + + + Outputs + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 48 + 16777215 + + + + 8 + + + 2 + + + true + + + false + + + + + + + + 96 + 16777215 + + + + Inputs + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 48 + 16777215 + + + + 4 + + + 2 + + + + + + + Auto-enable virtual ports + + + + + + + If checked, incoming data routes to the pattern +slot by channel number (0 to 15). + + + Record input into patterns by channel + + + + + diff --git a/seq_qt5/include/qseditoptions.hpp b/seq_qt5/include/qseditoptions.hpp index 064b7691..d5477e84 100644 --- a/seq_qt5/include/qseditoptions.hpp +++ b/seq_qt5/include/qseditoptions.hpp @@ -233,6 +233,7 @@ private slots: void slot_buss_override (); void slot_record_by_channel (); void slot_virtual_ports (); + void slot_enable_virtual_ports (); void slot_virtual_out_count (); void slot_virtual_in_count (); diff --git a/seq_qt5/src/qseditoptions.cpp b/seq_qt5/src/qseditoptions.cpp index f42f15e6..8e66916a 100644 --- a/seq_qt5/src/qseditoptions.cpp +++ b/seq_qt5/src/qseditoptions.cpp @@ -471,6 +471,14 @@ qseditoptions::setup_tab_midi_input () this, SLOT(slot_virtual_ports()) ); + bool enablevirtualports = rc().manual_auto_enable(); + ui->checkBoxAutoEnableVirtual->setChecked(enablevirtualports); + connect + ( + ui->checkBoxAutoEnableVirtual, SIGNAL(clicked(bool)), + this, SLOT(slot_enable_virtual_ports()) + ); + /* * The virtual port counts for input and output. */ @@ -3330,6 +3338,14 @@ qseditoptions::slot_virtual_ports () modify_rc(); } +void +qseditoptions::slot_enable_virtual_ports () +{ + bool on = ui->checkBoxAutoEnableVirtual->isChecked(); + rc().manual_auto_enable(on); + modify_rc(); +} + void qseditoptions::slot_virtual_out_count () { diff --git a/seq_rtmidi/src/mastermidibus.cpp b/seq_rtmidi/src/mastermidibus.cpp index 725a4109..ef367fb1 100644 --- a/seq_rtmidi/src/mastermidibus.cpp +++ b/seq_rtmidi/src/mastermidibus.cpp @@ -134,20 +134,31 @@ mastermidibus::api_init (int ppqn, midibpm bpm) midi_master().api_set_beats_per_minute(bpm); if (rc().manual_ports()) /* virtual ports */ { + bool enable = rc().manual_auto_enable(); int num_buses = rc().manual_port_count(); /* output count */ midi_master().clear(); for (int bus = 0; bus < num_buses; ++bus) /* output busses */ { midibus * m = make_virtual_bus(bus, midibase::io::output); if (not_nullptr(m)) + { + if (rc().manual_auto_enable()) + m->set_io_status(enable); + midi_master().add_output(m); /* must come 2nd */ + } } num_buses = rc().manual_in_port_count(); /* input count */ for (int bus = 0; bus < num_buses; ++bus) /* input busses */ { midibus * m = make_virtual_bus(bus, midibase::io::input); if (not_nullptr(m)) + { + if (rc().manual_auto_enable()) + m->set_io_status(enable); + midi_master().add_input(m); /* must come 2nd */ + } } } else