1#! /bin/bash
2
3set -e
4
5# use to copy the LV2 bundle gx_sceleton.lv2 to gx_${name}.lv2
6# generate a C++ file from the faust.dsp source (by dsp2cc)
7# generate a according name.ttl file
8# were ${name} is the first arg on comandline, usually the dsp file.
9# the dsp file needs to be stored in the faust folder.
10
11########################## functions ###################################
12
13usage() {
14  echo "usage: make_lv2_bundle {options} <cc|cpp|dsp-file> [<plugin class>] "
15  echo "options:"
16  echo "    -h:   show this help"
17  echo "    -s:   faust use single precision"
18  echo "    -d:   faust use double precision (default)"
19  echo "    -V:   faust use vectorize"
20  echo "    -S x: faust use vector size x"
21  echo "    -p:   path/to/source/sourcefile "
22  echo "    -n    effect name "
23  echo "    -r:   use resampler"
24  exit 1
25}
26
27function get_basename_ext() {
28case "$extension" in
29  dsp)
30    if [ "$2" = "" ]; then
31      bname="$(basename "$1" .dsp)"
32    else
33      bname="$(basename "$1" .dsp)"
34      effect_category="$2"
35    fi;;
36  cc)
37    if [ "$2" = "" ]; then
38      bname="$(basename "$1" .cc)"
39    else
40      bname="$(basename "$1" .cc)"
41      effect_category="$2"
42    fi;;
43  cpp)
44    if [ "$2" = "" ]; then
45      bname="$(basename "$1" .cpp)"
46    else
47      bname="$(basename "$1" .cpp)"
48      effect_category="$2"
49    fi;;
50  *)
51   echo -e $RED"file extension not supported"$NONE ; usage;;
52esac
53}
54
55function select_plugin_type() {
56  echo -e $WARNING'Please select a Plugin type from the list'$NONE
57  select type in "${Plugin_types[@]}" ; do
58    if [[ $type == "quit" ]]; then
59      break
60    fi
61    effect_category="$type"
62    if [ ! -z "$type" ]; then
63      break;
64    else
65      echo -e $WARNING"Select a number from the list!"$NONE
66    fi
67  done
68}
69
70function check_plugin_type() {
71  for I in "${Plugin_types[@]}"; do
72    [[ $I == $effect_category ]] && return 0
73  done
74  select_plugin_type
75  return 0
76}
77
78function check_dir() {
79  if [ ! -d gx_${bname}.lv2 ]; then
80    mkdir -p gx_${bname}.lv2
81  else
82    echo -e $WARNING"Directory gx_${bname}.lv2 already exist, should we remove it? Yes/No"$NONE
83    select yn in "Yes" "No"; do
84      case $yn in
85        Yes ) rm -rf gx_${bname}.lv2; mkdir -p gx_${bname}.lv2; break;;
86        No ) echo  -e $RED"No selected exit here"$NONE; exit 1;;
87      esac
88    done
89  fi
90}
91
92function dsptocc() {
93  if [ -f ${faustdir}/"$bname.$extension" ] ; then
94    if [ $extension == "dsp" ] ; then
95      echo -e $BLUE"generate $bname.cc and copy to gx_$bname.lv2"$NONE
96      set -e
97      "$tooldir"/dsp2cc  --init-type=plugin-lv2  \
98        $prec "${faustopt[@]}" -o gx_${bname}.lv2/"$bname.cc" ${faustdir}/"$bname.dsp"
99    else
100      echo -e $BLUE"copy $bname.$extension to gx_$bname.lv2/$bname.cc"$NONE
101      cp -r ${faustdir}/"$bname.$extension" gx_${bname}.lv2/"$bname.cc"
102    fi
103  else
104    echo  -e $RED"error: "${faustdir}/"$bname.$extension not found"$NONE; exit 1;
105  fi
106}
107
108
109function copy_sceleton() {
110  grep 'stereo_audio' gx_${bname}.lv2/$bname.cc >/dev/null && stereo="true"  || stereo="false"
111  if [ "$stereo" == "true" ] ; then
112    grep 'stereo_audio = 0;' gx_${bname}.lv2/$bname.cc >/dev/null && stereo="false"  || stereo="true"
113  fi
114
115  if [ "$stereo" == "false" ] ; then
116    echo -e "copy gx_sceletonX11.lv2 to "$BLUE"gx_$bname.lv2"$NONE" and rename/replace strings to "$BLUE"$bname"$NONE
117    if [ "$resample" == "YES" ] ; then
118      cp -r gx_sceleton_rs_X11.lv2/* gx_${bname}.lv2/
119    else
120      cp -r gx_sceletonX11.lv2/* gx_${bname}.lv2/
121    fi
122    j=3
123  else
124    echo -e "copy gx_sceletonX11_stereo.lv2 to "$BLUE"gx_$bname.lv2"$NONE" and rename/replace strings to "$BLUE"$bname"$NONE
125    if [ "$resample" == "YES" ] ; then
126      cp -r gx_sceleton_rs_X11_stereo.lv2/* gx_${bname}.lv2/
127    else
128      cp -r gx_sceletonX11_stereo.lv2/* gx_${bname}.lv2/
129    fi
130    j=5
131  fi
132
133  set +e
134  RN=$(rename -V  2>/dev/null| grep File::Rename)
135  if [ ! -z "$RN" ] ; then
136    use_to_rename='rename'
137  fi
138  if [ -z "$RN" ] ; then
139    RN=$(prename -V  2>/dev/null| grep File::Rename)
140    use_to_rename='prename'
141  fi
142  if [ -z "$RN" ] ; then
143    RN=$(perl-rename -V  2>/dev/null| grep File::Rename)
144    use_to_rename='perl-rename'
145  fi
146  if [ -z "$RN" ] ; then
147    RNUL=$(rename -V  2>/dev/null| grep util-linux)
148    if [ -z "$RNUL" ] ; then
149      RNUL=$(rename.ul -V  2>/dev/null| grep util-linux)
150      use_to_rename='rename.ul'
151    else
152      use_to_rename='rename'
153    fi
154  fi
155  set -e
156
157  if [ ! -z "$RN" ] ; then
158    cd ./gx_${bname}.lv2 && find . -depth -exec ${use_to_rename} 's/sceleton/'${bname}'/g' {} + && find . -depth -type f -exec  sed -i 's/sceleton/'${bname}'/g' {} +
159  elif [ ! -z "$RNUL" ] ; then
160    cd ./gx_${bname}.lv2 && find . -depth -exec ${use_to_rename} sceleton ${bname} {} +  && find . -depth -type f -exec  sed -i 's/sceleton/'${bname}'/g' {} +
161  else
162    cd ./gx_${bname}.lv2 && find . -depth -name "*sceleton*" -exec bash -c \
163    'for f; do base=${f##*/}; mv -- "$f" "${f%/*}/${base//sceleton/'${bname}'}"; done' _ {} + && \
164    find . -depth -type f -exec  sed -i 's/sceleton/'${bname}'/g' {} +
165  fi
166}
167
168function grep_ports_enums() {
169  echo -e "grep ports and copy them to  "$BLUE"gx_$bname.h"$NONE
170  cat "$bname.cc" | sed -n '/enum/,/PortIndex/p' |  sed '/enum/d;/PortIndex/d;/{/d;/}/d'>ports
171
172  sed -i -e '/BYPASS/r ports' "plugin/gx_$bname.h"
173  echo -e "grep ports values and enums and copy them to "$BLUE"gx_$bname.ttl"$NONE
174  cat "$bname.cc" | sed -n '/data;/{p;g;1!p;};h' | sed 's/ , /\n/;s/.*\n//;s/case//g;s/,/ ;/g;s/://g;s/	 //g;s/  //g;s/ //g;s/$/;/' | sed '$!N;s/\n//'>ports
175  cat "$bname.cc" | sed -n '/value_pair/{p;n;1!p;};h' | sed 's/{/\n/;s/.*\n//;s/ , /\n/;s/.*\n//;s/case//g;s/}//g;s/{//g;s/;//g;s/,/ ;/g;s/://g;s/	 //g;s/;0//g;s/  //g;s/ //g;s/$/;/' > enums
176}
177
178function make_ui() {
179  echo "generate GUI"
180  COUNTER=0
181  ACOUNTER=1
182  PCOUNTER=0
183  ECOUNTER=0
184  PLACE=110
185  MODEL='SWITCH'
186  match=0
187  enum_var1=""
188  enum_var=""
189  cat enums >enums1
190  while IFS=$';' read -r -a line; do
191    while IFS=$';' read -r -a myEnum; do
192      if [ -z "${myEnum[0]}" ]; then
193        match=0
194      else
195        a=${#myEnum[@]}
196        if (($a==1)); then
197          if [ ${line[4]} == ${myEnum[0]} ]; then
198            match=1
199            sed -i -e "1,2d" enums1
200            break
201          fi
202        else
203          match=0
204          if (($a==2)); then
205            MODEL='SWITCH'
206          else
207            MODEL='ENUM'
208          fi
209          FLOAT=${myPorts[1]}
210          i=${FLOAT/\.*}
211          i=${i/e/}
212          enum_var1+="	//static const char enum"${line[4]}"[] = {"
213          for (( c=0; c<a; c++ )); do
214            enum_var1+="${myEnum[c]},"
215            i=$[i+1]
216          done
217          enum_var2="${enum_var1::-1}"
218          enum_var2+="};\n"
219        fi
220      fi
221    done < enums1
222    if (($match==1)); then
223
224      conts+='	ui->controls['${ACOUNTER}'] = (gx_controller) {{ '${line[0]}', '${line[0]}', '${line[1]}', '${line[2]}', '${line[3]}'}, {'${PLACE}', 30, 61, 61}, false,\"'${line[4]}'\", '${MODEL}', '${line[4]}'};\n'
225      let COUNTER=COUNTER+1
226      let ACOUNTER=ACOUNTER+1
227      let PLACE=PLACE+70
228
229      enum_var+=$enum_var2
230      #enum_var+="  static const size_t enum"${line[4]}"_size = sizeof(enum"${line[4]}") / sizeof(enum"${line[4]}"[0]);\n"
231      #enum_var+="  make_selector_box(\&m_vboxs["${ECOUNTER}"],\""${line[4]}"\", enum"${line[4]}", enum"${line[4]}"_size, 0,1.0, "${line[4]}");\n"
232     # ports+='    case '${line[4]}':\n      return \&m_selector['${ECOUNTER}'];\n'
233      let ECOUNTER=ECOUNTER+1
234      enum_var1=""
235      match=0
236    else
237      enum_var1=""
238      conts+='	ui->controls['${ACOUNTER}'] = (gx_controller) {{'${line[0]}', '${line[0]}', '${line[1]}', '${line[2]}', '${line[3]}'}, {'${PLACE}', 30, 61, 61}, false,\"'${line[4]}'\", KNOB, '${line[4]}'};\n'
239
240    #  conts+='    make_controller_box(ui->vkbox['${COUNTER}'], ui->knob['${COUNTER}'], ui->adj['${COUNTER}'], ui->label['${COUNTER}'], (const char*)\"'${line[4]}'\", ui, ui->args['${COUNTER}'], '${line[4]}');\n'
241      ports+='    case '${line[4]}':\n      return \&m_bigknob['${COUNTER}'];\n'
242      let COUNTER=COUNTER+1
243      let ACOUNTER=ACOUNTER+1
244      let PLACE=PLACE+70
245    fi
246  done < ports
247  #let PCOUNTER=COUNTER-1
248  sed -i "s/PORTS/${ports}/g;s/CONTS/${conts}/g;s/VARI/${ACOUNTER}/g;s#ENUMS#${enum_var}#g;s/VAI/${ECOUNTER}/g;" gui/gx_${bname}_x11ui.c
249 #  sed -i "s/VAR/${PCOUNTER}/g;s/VAI/${ECOUNTER}/g;" gx_${bname}_ui.c
250  rm -rf enums1
251  if [ ! -z "$effect_name" ]; then
252    EFNAME=${effect_name^^}
253    efname=${effect_name}
254    sed -i 's/EffectNAME/'"${effect_name}"'/g'  gui/gx_${bname}_x11ui.c
255    echo -e "set plugin name to "$BLUE"Gx$effect_name"$NONE
256  else
257    EFNAME=${bname^^}
258    efname=${bname}
259    sed -i 's/EffectNAME/'${bname}'/g'  gui/gx_${bname}_x11ui.c
260    sed -i 's/EFNAME/'"${EFNAME}"'/g'  gui/gx_${bname}_x11ui.c
261    echo -e "set plugin name to "$BLUE"Gx$bname"$NONE
262  fi
263}
264
265function make_ttl() {
266  match=0
267
268  while IFS=$';' read -r -a myPorts; do
269    while IFS=$';' read -r -a myEnum; do
270      if [ -z "${myEnum[0]}" ]; then
271        match=0
272      else
273        a=${#myEnum[@]}
274        if (($a==1)); then
275          if [ ${myPorts[4]} == ${myEnum[0]} ]; then
276            match=1
277            sed -i -e "1,2d" enums
278            break
279          fi
280        else
281          match=0
282          FLOAT=${myPorts[1]}
283          i=${FLOAT/\.*}
284          i=${i/e/}
285          for (( c=0; c<a; c++ )); do
286            enum_var1+="        lv2:scalePoint [rdfs:label "${myEnum[c]}"; rdf:value "${i}"];\n"
287            i=$[i+1]
288          done
289        fi
290      fi
291    done < enums
292    echo '      , [
293        a lv2:InputPort ,
294            lv2:ControlPort ;
295        lv2:index' $j' ;
296        lv2:symbol "'${myPorts[4]}'" ;
297        lv2:name "'${myPorts[4]}'" ;'
298    echo '        lv2:default '${myPorts[0]}' ;
299        lv2:minimum '${myPorts[1]}' ;
300        lv2:maximum '${myPorts[2]}' ;'
301    if (($match==1)); then
302      echo '        lv2:portProperty lv2:integer;
303        lv2:portProperty lv2:enumeration ; '
304      echo -e "$enum_var1"
305      enum_var1=""
306      match=0
307    fi
308    echo -n '    ]'
309    j=$[j+1]
310    enum_var1=""
311  done < ports >> plugin/gx_$bname.ttl
312  echo " .
313
314<http://guitarix.sourceforge.net/plugins/gx_${bname}_gui#_${bname}_>
315  a guiext:X11UI;
316  guiext:binary <gx_${bname}_ui.so>;
317        lv2:extensionData guiext::idle ;
318        lv2:requiredFeature guiext:makeResident;
319  ." >> plugin/gx_$bname.ttl
320
321  if [ ! -z "$effect_category" ]; then
322    sed -i 's/EffectPlugin/'${effect_category}'/g'  plugin/gx_${bname}.ttl
323    echo -e "set plugin class to "$BLUE"$effect_category"$NONE
324  fi
325  if [ ! -z "$effect_name" ]; then
326    sed -i 's/EffectNAME/'"${effect_name}"'/g'  plugin/gx_${bname}.ttl
327  else
328    sed -i 's/EffectNAME/'${bname}'/g'  plugin/gx_${bname}.ttl
329  fi
330
331  rm -rf ports
332  rm -rf enums
333}
334
335function byby() {
336  mv -f "$bname.cc" "dsp/$bname.cc"
337  echo -e $BLUE"Okay, gx_${bname}.lv2 is done"$NONE
338  echo  -e $BLUE"Now you can enter ./gx_${bname}.lv2
339  and run make && make install"$NONE
340}
341
342########################## supported plugin types ######################
343
344Plugin_types=(
345        'DelayPlugin'
346            'ReverbPlugin'
347        'DistortionPlugin'
348            'WaveshaperPlugin'
349        'DynamicsPlugin'
350            'AmplifierPlugin'
351            'CompressorPlugin'
352            'EnvelopePlugin'
353            'ExpanderPlugin'
354            'GatePlugin'
355            'LimiterPlugin'
356        'FilterPlugin'
357            'AllpassPlugin'
358            'BandpassPlugin'
359            'CombPlugin'
360            'EQPlugin'
361               'MultiEQPlugin'
362                'ParaEQPlugin'
363            'HighpassPlugin'
364            'LowpassPlugin'
365        'GeneratorPlugin'
366            'ConstantPlugin'
367            'InstrumentPlugin'
368            'OscillatorPlugin'
369        'ModulatorPlugin'
370            'ChorusPlugin'
371            'FlangerPlugin'
372            'PhaserPlugin'
373        'ReverbPlugin'
374        'SimulatorPlugin'
375            'ReverbPlugin'
376        'SpatialPlugin'
377        'SpectralPlugin'
378            'PitchPlugin'
379        'UtilityPlugin'
380            'AnalyserPlugin'
381            'ConverterPlugin'
382            'FunctionPlugin'
383            'MixerPlugin' )
384
385
386
387###################### global variables ################################
388
389BLUE="\033[1;34m"
390RED="\033[1;31m"
391WARNING='\033[93m'
392NONE="\033[0m"
393
394tooldir=../../../
395faustdir=./tmp
396instdir="$tooldir"/.."$(dirname "$0")"
397prec="--double"
398faustopt=()
399copy=0
400bname=""
401effect_category=""
402effect_name=""
403resample=""
404
405############################# main #####################################
406
407while getopts hn:sdVSp:rc OPT; do
408  sc=0
409  case "$OPT" in
410  h) usage;;
411  n) effect_name=$OPTARG;;
412    # echo -e "name $effect_name";;
413  s) prec="--float";;
414  d) prec="--double";;
415  V) faustopt+=(--vectorize);;
416  S) faustopt+=(--add="-vs $OPTARG");;
417  p) faustdir="$(dirname "$2")/"
418     file="$(basename "$2")"
419     sc=1;;
420  r) resample="YES";;
421  c) copy=1;;
422  \?) usage;;
423  esac
424  #if [ $OPTIND != 1 ] # This test fails only if multiple options are stacked
425  #                      # after a single -.
426 # then    shift $((OPTIND - 1 + sc))
427 #    OPTIND=1
428 # fi
429 #  echo "loop"
430done
431
432#shift $(expr $OPTIND - 1)
433#[ "$1" = "" ] && usage
434extension="${file##*.}"
435echo -e "$effect_name"
436######################## function calls ################################
437
438get_basename_ext "$file" "$2"
439check_plugin_type && echo -e "Plugin type "$BLUE"$effect_category"$NONE
440check_dir
441dsptocc
442copy_sceleton
443grep_ports_enums
444make_ui
445make_ttl
446byby
447
448############################ EOF #######################################
449
450exit
451