#!/bin/bash
#
#******************************************************************************
# jackctl
#------------------------------------------------------------------------------
##
# \file           jackctl
# \library        Any project
# \author         Chris Ahlstrom
# \date           2022-09-25
# \update         2024-12-03`
# \version        $Revision$
# \license        $XPC_SUITE_GPL_LICENSE$
#
#     The above is modified by the following to remove even the mild GPL
#     restrictions:
#
#     Use this script in any manner whatsoever.  You don't even need to give
#     me any credit.  However, keep in mind the value of the GPL in keeping
#     software and its descendant modifications available to the community
#     for all time.
#
#     See "jack_control --help" for a list of options.
#
# ALSA parameters partial list:
#
#     device:        ALSA device name (type:isset:default:value).
#     capture:       Optionally set port (str:notset:none:none).
#     playback:      Optionally set port (str:notset:none:none).
#     rate:          Set the sample rate (48000).
#     period:        Frames per period (the "cycle", time between process
#                    callback calls (1024).
#     nperiod:       Number of periods (cycles) of latency (2).
#     midi-driver:   ALSA MIDI driver.
#
# /proc/asound/cards (on our system):
#
#     0: CODEC       USB audio box.
#     1: nanoKEY2    Korg keyboard.
#     2: HDMI        Onboard HDMI.
#     3: PCH         Intel on-board sound.
#     4: NVidia      Onboard NVidia card.
#     5: Midi        A generic USB MIDI cable.
#     6: Mini        LaunchPad Mini.
#
# Configuration file:
#
#     The configuration file affected by jack_control is:
#
#        ~/.config/jack/conf.xml
#
#------------------------------------------------------------------------------

JCTL_OPERATION="list"
JCTL_DRIVER="alsa"
JCTL_DEVICE="hw:CODEC"  # see "cat /proc/asound/cards"
JCTL_RATE="48000"
JCTL_LATENCY="2"
JCTL_PERIOD="256"      # for TESTING
JCTL_A2JMIDID="no"

if [ "$1" == "--help" ] || [ "$1" == "help" ] ; then

   cat << E_O_F
Usage v. 2024-12-03`

   jackctl [ --start ] [ options ]     Start with the usual parameters:

Options:

   --list      List the drivers and the ALSA/JACK parameters. [Default]
   --start     Start the JACK server.
   --stop      Stop the JACK server.
   --kill      Stop the JACK server and exit jackdbus.
   --set       Set the default values, shown here.  Stops, then restarts
               jackdbus. Edit this script to change the defaults:

               Driver:       $JCTL_DRIVER
               Device:       $JCTL_DEVICE
               Frame rate:   $JCTL_RATE
               Nperiods:     $JCTL_LATENCY
               Frame period: $JCTL_PERIOD frames
               A2jmidid:     $JCTL_A2JMIDID

   --period F  Change the period of the JACK server, and restart it.
   --nperiod P Change ALSA period (playback latency, 2 or 3).
   --rate R    Change the "sample rate".
   --a2j       Also start/stop a2jmidid.
   --help      Show this message.

Getting tired of qjackctl and jackdbus wrestling with each other on
a newer Ubuntu system that runs jackdbus.
E_O_F

exit 0

else

   while [ "$1" != "" ] ; do

      case "$1" in

         --list | list)
            JCTL_OPERATION="list"
            ;;

         --set | set)
            JCTL_OPERATION="setdefaults"
            ;;

         --start | start)
            JCTL_OPERATION="start"
            ;;

         --stop | stop)
            JCTL_OPERATION="stop"
            ;;

         --kill | kill)
            JCTL_OPERATION="kill"
            ;;

         --rate | rate)
            shift
            JCTL_RATE="$1"
            JCTL_OPERATION="setrate"
            ;;

         --period | period)
            shift
            JCTL_PERIOD="$1"
            JCTL_OPERATION="setperiod"
            ;;

         --nperiod | nperiod)
            shift
            JCTL_LATENCY="$1"
            ;;

         --a2j | a2j)

            JCTL_A2JMIDID="yes"
            ;;

         *)
            echo "? Unsupported option; --help for more information"
            exit 1
            ;;

      esac
      shift

   done

fi

if [ "$JCTL_OPERATION" == "list" ] ; then

   echo "Available sound sinks:"
   cat /proc/asound/cards | grep "^[ 0-9][0-9]"
   echo "Selecting ALSA (seq). Available parameters:"
   jack_control ds $JCTL_DRIVER
   jack_control dp | grep "ALSA\|rate:\|period:\|nperiods:"

elif [ "$JCTL_OPERATION" == "stop" ] ; then

   if [ "$JCTL_A2JMIDID" == "yes" ] ; then
      killall -9 a2jmidid
      sleep 1
   fi
   jack_control stop

elif [ "$JCTL_OPERATION" == "kill" ] ; then

   if [ "$JCTL_A2JMIDID" == "yes" ] ; then
      killall -9 a2jmidid
      sleep 1
   fi
   jack_control stop
   jack_control exit

elif [ "$JCTL_OPERATION" == "start" ] ; then

   jack_control start
   sleep 2
   if [ "$JCTL_A2JMIDID" == "yes" ] ; then
      a2jmidid --export-hw &
   fi
   jack_lsp --aliases

elif [ "$JCTL_OPERATION" == "setperiod" ] ; then

   echo "Setting JACK frame count to $JCTL_PERIOD"
   jack_control stop
   jack_control dps period $JCTL_PERIOD
   jack_control start
   jack_control dp | grep "ALSA\|rate:\|period:\|nperiods:"

elif [ "$JCTL_OPERATION" == "setrate" ] ; then

   echo "Setting JACK frame rate to $JCTL_RATE"
   jack_control stop
   jack_control dps rate $JCTL_RATE
   jack_control start
   jack_control dp | grep "ALSA\|rate:\|period:\|nperiods:"

elif [ "$JCTL_OPERATION" == "setdefaults" ] ; then

   jack_control stop
   jack_control ds $JCTL_DRIVER
   jack_control dps device $JCTL_DEVICE
   jack_control dps rate $JCTL_RATE
   jack_control dps nperiods $JCTL_LATENCY
   jack_control dps period $JCTL_PERIOD
   jack_control start
   jack_control dp | grep "ALSA\|rate:\|period:\|nperiods:"

fi

#******************************************************************************
# jackctl
#------------------------------------------------------------------------------
# vim: ts=3 sw=3 et ft=sh
#------------------------------------------------------------------------------
