#!/bin/bash #========================================================================== # art2script # # v 1.5 # # This script will generate a Scripter script when provided # with an ArticulationSet Plist file, it will use all keyswitches # found in the OUTPUT section of the ArticulationSet. # After generating this script, the OUTPUT section of the articulation set # should be cleared to blank by the user #========================================================================== # Usage message function usage() { echo 1>&2 echo "Usage: $0 [options] " 1>&2 echo 1>&2 echo "Options:" 1>&2 echo 1>&2 echo " --id|-i (default) Produces full script based on articulationID" 1>&2 echo " --lane|-l Produces full script based on automation lane" 1>&2 echo " --array|-a Only output the ART array" 1>&2 echo " --port|-p Specify midi port, default=1" 1>&2 echo " --channel|-c Specify midi channel, default=1" 1>&2 echo " --help|-h Usage Info" 1>&2 echo 1>&2 } # First translate long option names for arg in "$@"; do shift case "$arg" in "--array") set -- "$@" "-a" ;; "--id") set -- "$@" "-i" ;; "--lane") set -- "$@" "-l" ;; "--port") set -- "$@" "-p" ;; "--channel") set -- "$@" "-c" ;; "--help") set -- "$@" "-h" ;; *) set -- "$@" "$arg" esac done # Now parse the actual command line for options OPTIND=1 ARRAYONLY=false LANE=false CHANNUM=1 PORTNUM=1 while getopts ":alip:c:h" opt; do case $opt in a) # Array only ARRAYONLY=true ;; i) # articulationID mode (default) LANE=false ;; p) # specify port PORTNUM=${OPTARG} ;; c) # specify channel CHANNUM=${OPTARG} ;; l) # Automation Lane mode LANE=true ;; h) usage exit 0 ;; \?) echo "ERROR: Invalid Option" 1>&2 usage exit 1 ;; esac done # remove the options so we can process file name shift $(expr $OPTIND - 1) # check for file name provided if [ $# -lt 1 ] then echo "ERROR: Missing articulation set plist filename" 1>&2 usage exit 1 fi FILE=$1 if [ ! -f "$FILE" ] then echo "ERROR: File Not Found: $FILE" >&2 usage exit 1 fi #====================================== # verified all cmd line args, proceed #====================================== PB="/usr/libexec/PlistBuddy -c" #============================ # function handleSwitch() #============================ handleSwitch () { local lKidx=$1 local lArtID=$2 local lKs=$3 local lVel=$4 local lStatus="$5" if [ ${lKidx} -lt 1 ] then echo -n " ART[${PORTNUM}][${CHANNUM}][${lArtID}] = {name:\"${artName}\", ks:[" else echo -n "," fi #============================ # Handle NoteOn switches #============================ if [ "$lStatus" = "Note On" ] then echo $lKs | awk ' BEGIN { split("C|C#|D|D#|E|F|F#|G|G#|A|A#|B", rootNames, "|") for(i=0; i<128; i++) { octave= int(i/12)-2""; name[i] = rootNames[i%12 + 1]""octave } } { printf("\"%s\"", name[$0+0]); }' #============================ # Handle CC switches #============================ elif [ $lStatus = "Controller" ] then echo -n "[${lKs},${lVel}]" fi } if [ $ARRAYONLY = false ] then if [ $LANE = true ] then SVER="lanekeyswitcher v1.2" else SVER="keyswitcher v1.2" fi cat </dev/null` echo echo " /*****************************************************" echo " * port:${PORTNUM} channel:${CHANNUM} instrument: ${artsetName%.*}" echo " *****************************************************/" echo if [ $LANE = true ] then echo " /* initLane */" echo " initLane( ${PORTNUM}, ${CHANNUM}, \"${artsetName%.*}\" );" echo fi #============================================== # Loop through OUTPUT section of Articulations #============================================== idx=0 kidx=0 nextID=0 while [ true ] do artID=`${PB} "Print Articulations:${idx}:ArticulationID" "${FILE}" 2>/dev/null` if [ $? -ne 0 ] then break #no more articulations fi artID=`echo ${artID} | xargs` # If in LANE mode, just use consecutive ID values if [ $LANE = true ] then nextID=$((nextID+1)) artID=$nextID fi artName=`${PB} "Print Articulations:${idx}:Name" "${FILE}" 2>/dev/null` found=false # Try non-array version of Output first status=`${PB} "Print Articulations:${idx}:Output:Status" "${FILE}" 2>/dev/null` if [ $? -eq 0 ] #================================ # Handle single switch non-array #================================ then found=true ks=`${PB} "Print Articulations:${idx}:Output:MB1" "${FILE}" 2>/dev/null` ks=`echo $ks | xargs` vel=`${PB} "Print Articulations:${idx}:Output:ValueLow" "${FILE}" 2>/dev/null` if [ $? -ne 0 ] then vel=1 else vel=`echo $vel | xargs` fi handleSwitch 0 ${artID} ${ks} ${vel} "${status}" #======================================= # Handle multi-switch array #======================================= else kidx=0; while [ true ] do status=`${PB} "Print Articulations:${idx}:Output:${kidx}:Status" "${FILE}" 2>/dev/null` if [ $? -ne 0 ] then break fi found=true ks=`${PB} "Print Articulations:${idx}:Output:${kidx}:MB1" "${FILE}" 2>/dev/null` ks=`echo $ks | xargs` vel=`${PB} "Print Articulations:${idx}:Output:${kidx}:ValueLow" "${FILE}" 2>/dev/null` if [ $? -ne 0 ] then vel=1 else vel=`echo $vel | xargs` fi handleSwitch ${kidx} ${artID} ${ks} ${vel} "${status}" kidx=$((kidx+1)) done fi #========================================= # If there were keyswitches, end the line #========================================= if [ $found = true ] then echo "]}; " #echo -n "/" #echo "/ ${artName}" fi # Increment idx idx=$((idx+1)) done # If array only then get out if [ $ARRAYONLY = true ] then exit 0 fi # Finish Initialize function echo " // etc" echo "}" # Now output the actual guts of the script if [ $LANE = true ] # Automation Lane handling then cat <