%-------------------------------------------------------------------------------
% seq66 headless
%-------------------------------------------------------------------------------
%
% \file        seq66 headless.tex
% \library     Documents
% \author      Chris Ahlstrom
% \date        2018-09-30
% \update      2023-10-31
% \version     $Revision$
% \license     $XPC_GPL_LICENSE$
%
%     Provides a discussion of the MIDI GUI headless that Seq66
%     supports.
%
%-------------------------------------------------------------------------------

\section{Seq66 Headless Version}
\label{sec:headless}

   \textsl{Seq66} can be built as a command-line application.
   That is, \textsl{Seq66}
   can be run from the command-line, with no visible user interface.
   See the \texttt{INSTALL} file provided with the source code distribution.
   Note the \texttt{--both} bootstrap option to build the GUI and CLI
   versions of \textsl{Seq66} at the same time.

   It can also be instantiated as a Linux daemon, for totally headless usage.
   Because there is no visibility into a headless process, the
   setup for \texttt{seq66cli} is tricky, and the musician must get
   used to blind MIDI control.

   Also see \sectionref{subsec:configuration_command_line}

\subsection{Seq66 Headless Setup}
\label{subsec:headless_setup}

   The first step in setting up a headless \texttt{seq66cli} session is
   to make sure that the GUI version (\texttt{seq66}) works as expected.
   The GUI and headless configurations need to do the following:
   
   \begin{enumerate}
      \item Access the correct inputs, especially a keyboard or pad controller
         that can be used for controlling the sequencer via MIDI, as well as
         inputing notes.
      \item The desired MIDI controller input buss must be \textsl{enabled}
         by setting the active bit to "1" for that device.
      \item The MIDI controller input must be configured with some
         \texttt{[automation-control]}
         values, so that the headless sequencer can stop and
         start playback, select the next playlist or song, or activate other
         sequencer controls.
         This is done by providing the name of a suitable
         \texttt{[midi-control-file]} ('ctrl') specified in the 'rc' file,
         and making sure it is marked as \texttt{active = true}.
      \item Configure a separate MIDI buss to use to record from another
         MIDI instrument.
      \item Access the desired outputs, in order to play sounds.  This can
         sometimes be tricky, because \textsl{Seq66} can route all
         patterns to the same output, or can let the patterns decide the
         outputs for themselves.
      \item The desired output busses must be \textsl{enabled} by setting
         the active bit to "1" for those device.
         Note that some MIDI controllers can be used to show
         the status of the music, and would also be configured in
         the 'ctrl' file.
      \item Create a play-list.  The headless sequencer can only select
         songs to play via a pre-configured play-list, or by placing
         a single song file on the command line.
      \item Run \texttt{seq66cli} and then stop it (Ctrl-C) to regenerate
         and verify the initial configuration files,
         \texttt{HOME/.config/seq66/seq66cli.*}.
   \end{enumerate}

   Once the above steps are proven for the \texttt{qseq66} configuration files,
   then the same settings can be made for the \texttt{seq66cli} configuration
   files.
   The easiest way to do this is to use a difference editor to
   make the settings match.  For example:

   \begin{verbatim}
      $ gvimdiff ~/.config/seq66/seq66cli.rc ~/.config/seq66/qseq66.rc
   \end{verbatim}

   Sometimes odd problems, such as the output synthesizer not working
   or not appearing in the list of outputs, can be a real puzzle.
   Here are the steps used in this test, based on sample files provided in the
   \texttt{contrib/midi}, \texttt{data/midi}, and \texttt{data/samples}
   directory; adapt them to your setup.  For
   simplicity, JACK is not running, and so ALSA is in force.

   \textbf{First}, after booting, plug in the MIDI keyboard or MIDI control
   pad.  Our example here will use the \textsl{Korg nanoKEY2} keyboard.  
   (For a more powerful and exhaustive setup, see
   \sectionref{sec:launchpad_mini}.)

   \textbf{Second}, start the desired (software) synthesizer.
   Here we use the synth \textsl{Yoshimi}, with a stock setup from the
   \textsl{Yoshimi Cookbook} project.
   The order of starting the keyboard/pad and the synthesiser
   will alter the port numbers of these items.  Best to do things in the same
   order every time... be consistent (or use the port-mapping feature
   described in \sectionref{sec:port_mapping}).
   Run the following command in order to verify the ALSA buss numbers for
   the controller and the synthesizer:

   \begin{verbatim}
      $ aplaymidi -l       # list ALSA output ports
      $ arecordmidi -l     # list ALSA input ports (except the 'announce' port)
   \end{verbatim}

   Another way is to start \texttt{qseq66}, exit it,
   and see the results in the \texttt{qseq66.rc} file.

   \textbf{Third}, edit the \texttt{seq66cli.rc}
   file as described below so that the correct settings of
   \texttt{[midi-clock]}, \texttt{[midi-input]} and
   \texttt{[midi-control-file]} are entered into the 'rc' configuration.
   For this discussion, we use a MIDI-control file 
   (\texttt{nanomap.ctrl}), which we set up
   in the \texttt{seq66cli.rc} file to be read.
   The \texttt{nanomap.ctrl} file sets up the \textsl{nanoKEY2} as
   shown in this figure:

\begin{figure}[H]
   \centering 
   \includegraphics[scale=1.5]{configuration/ctrl/nanokey-sample-rc.png}
   \caption{Sample nanoKEY2 Control Setup}
   \label{fig:headless_nanokey2_setup}
\end{figure}

   In this figure, the \textbf{OCT -} button on the
   \textsl{nanoKEY2} is pressed until
   it is flashing (not seen in the figure).
   This means that the lowest note on the
   \textsl{nanoKEY2} is MIDI note 0, the lowest
   note possible.
   With these settings, the playlists and songs can be loaded,
   and then played and paused.
   The \texttt{seq66cli.rc} file is edited to specify the desired 'ctrl' file:

   \begin{verbatim}
      [midi-control-file]
      active = true
      name = "nanomap.ctrl"      # assumed to reside in ~/.config/seq66
   \end{verbatim}

   The \texttt{seq66cli.rc} file should also enable the desired MIDI input
   control device:

   \begin{verbatim}
      [midi-input]
      4 1    "[1] 0:1 nanoKEY2 MIDI 1"
   \end{verbatim}

   This setting should match the \texttt{control-buss} setting in the
   the \texttt{nanomap.ctrl} file.  The \texttt{nanomap.ctrl} file is included
   in the \texttt{data/samples} directory of the source-code package or the
   installation directory.  The following initial settings in this file are
   relevant:

   \begin{verbatim}
		control-buss = 4					# adjust based on "aplaymidi -l"
		midi-enabled = true
   \end{verbatim}

   The various "midi-control-out" settings are not relevant for this test since
   the \texttt{nanoKEY2} cannot display statuses.
   For the rest of the setup, do these steps:

   \begin{enumerate}
      \item Copy the contents of of \texttt{data/seq66cli/} to
         \texttt{HOME/.config/seq66}.
      \item Copy \texttt{data/samples/sample.playlist} and
         \texttt{data/samples/sample.playlist} to \linebreak
         \texttt{HOME/.config/seq66}.
      \item In your HOME directory, create a soft link to the Seq66 project
         (source code and data) directory: \texttt{ln -s path/to/seq66}.
   \end{enumerate}

   \textbf{Fourth}, to validate the setup visibly, run a command from the
   command-line such as:

   \begin{verbatim}
      $ qseq66 --config seq66cli --buss 2 --verbose
   \end{verbatim}

%  --playlist data/sample.playlist

   The buss number ("2") may need to be different on your setup to get sound
   routed to the correct synthesizer.
   Also, the path to the playlist might
   need to be an absolute path; normally playlists are stored in the
   \texttt{HOME/.config/seq66} directory and accessed from there.
   Verify that the main window shows the playlist name,
   and that the arrow keys modify the
   play-list and song selection.
   If that works, verify that the MIDI keyboard
   or pad controller works to change the selection.
   Verify that the current
   song plays through the synthesizer that was started.
   Also verify that all
   songs have been directed to the desired port(s) for each song.
   If this setup works (MIDI controls have the proper effect and the tunes play
   through the synthesizer), proceed to the next step.

   \textbf{Fifth}, test the command-line \textsl{Seq66} by running the
   following command (your setup might vary) on the command line:

   \begin{verbatim}
      $ seq66cli --buss 2 --verbose --playlist data/sample.playlist
   \end{verbatim}

   There is a play-list option to automatically unmute the sets when a new song
   is selected.  If set, then the first song should be ready to play.
   If it plays, and the play-list seems to work (as indicated by the console
   output and the proper playback), then set up to run \texttt{seq66cli}
   as a daemon:

   \begin{verbatim}
      $ seq66cli -o daemonize
   \end{verbatim}

   Then it is good to solidify the setup by editing the 'rc' and 'usr' files.

%  The keyboard controls and sound output should work.
%  However, at present the daemon doesn't get the proper settings, so that is
%  something to work on for version 0.95.
   One can create a shortcut to run the application in the background (i.e. not
   as a daemon..
   In a \textsl{Fluxbox} menu:

   \begin{verbatim}
   [exec] (Seq66 Headless) {/usr/bin/seq66cli --jack-midi --jack-master --bus 6}
   \end{verbatim}

   For a sophisticated control setup, see \sectionref{sec:launchpad_mini}.
   For a much more complete setup:

   \begin{enumber}
      \item Run the seq66cli program and hit \texttt{Ctrl-C} to exit.
      \item Verify that there are a number of \texttt{seq66cli.*}
         files in the \texttt{~/.config/seq66} directory.
         There will also be a log-file to examine to see if all is good.
      \item In \texttt{seq66cli.rc}:
      \begin{enumber}
         \item Verify that \texttt{[usr-file]}
            is active and specifies \texttt{seq66cli.usr}.
         \item Activate a \texttt{[midi-control-file]} that supports
            MIDI control and MIDI status display for your setup.
            Otherwise, the program will be nearly impossible to use.
         \item If you have mutes, playlist, and note-mapper (drums) files to 
             use, specify them and activate them.
         \item Verify the ports and port-mapping are appropriate for
            both your setup and for the songs to be created or played.
         \item Verify that the JACK settings are correct (or set up to use
            ALSA).
      \end{enumber}
      \item In \texttt{seq66cli.usr}:
      \begin{enumber}
         \item Verify that the \texttt{[usr-midi-ppqn]} settings are
            as desired.
         \item Modify the \texttt{[user-options]} settings as desired.
         \item Set daemonize if desired. Might consider installing
            \texttt{seq66cli} as a service.
            We don't yet provide any real help for that use case.
         \item Change the log-file name if desired, or change it to "" to
            send output to /dev/null.
      \end{enumber}
   \end{enumber}

\subsection{Seq66 Headless Stopping}
\label{subsec:headless_stopping}

   If running \textsl{seq66cli} from a console, a simple
   \texttt{Ctrl-C} will stop the application.

   If it is running as a daemon, use the following command from a console,
   or set up a menu entry to run this command:

   \begin{verbatim}
      $ killall seq66cli
   \end{verbatim}

   (Not sure if it is worth adding a "--kill" option to
   \textsl{seq66cli}... killall is fairly complex.)

%-------------------------------------------------------------------------------
% vim: ts=3 sw=3 et ft=tex
%-------------------------------------------------------------------------------
