1#!/usr/local/bin/bash -e 2 3##################################################################### 4# # 5# Compiles Faust programs to Max externals # 6# using simple precision samples # 7# (c) Grame, 2012-2019 # 8# # 9##################################################################### 10 11. faustpath 12. faustoptflags 13. usage.sh 14 15CXXFLAGS+=" $MYGCCFLAGSGENERIC" # So that additional CXXFLAGS can be used 16 17OSCDEFS="" 18OSCLIB="" 19NVOICES=-1 20EFFECT="" 21SOUNDFILE="0" 22SOUNDFILEDEFS="" 23SOUNDFILELIBS="" 24US="0" 25DS="0" 26FILTER="0" 27 28# path to max SDK 29# MAXSDK is declared in faustpath 30MAXINC=$MAXSDK/max-includes 31MSPINC=$MAXSDK/msp-includes 32 33createInfoPList() { 34( 35 echo '<?xml version="1.0" encoding="UTF-8"?>' 36 echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' 37 echo '<plist version="1.0">' 38 echo '<dict>' 39 echo ' <key>CFBundleDevelopmentRegion</key>' 40 echo ' <string>English</string>' 41 echo ' <key>CFBundleExecutable</key>' 42 echo " <string>$1</string>" 43 echo ' <key>CFBundleIconFile</key>' 44 echo ' <string></string>' 45 echo ' <key>CFBundleIdentifier</key>' 46 echo " <string>com.grame.$1</string>" 47 echo ' <key>CFBundleInfoDictionaryVersion</key>' 48 echo ' <string>1.0.0</string>' 49 echo ' <key>CFBundlePackageType</key>' 50 echo ' <string>iLaX</string>' 51 echo ' <key>CFBundleSignature</key>' 52 echo ' <string>max2</string>' 53 echo ' <key>CFBundleVersion</key>' 54 echo ' <string>1.0.0</string>' 55 echo ' <key>CFBundleShortVersionString</key>' 56 echo ' <string>1.0.0</string>' 57 echo ' <key>CFBundleLongVersionString</key>' 58 echo " <string>$1 1.0.0, Copyright 2012-2018 Grame</string>" 59 echo ' <key>CSResourcesFileMapped</key>' 60 echo ' <true/>' 61 echo '</dict>' 62 echo '</plist>' 63 ) > "$2" 64} 65 66#------------------------------------------------------------------- 67# Analyze command arguments : 68# faust options -> OPTIONS 69# if -omp : -openmp or -fopenmp -> OPENMP 70# existing *.dsp files -> FILES 71# 72 73# dispatch command arguments 74while [ $1 ] 75do 76 p=$1 77 78 if [ $p = "-help" ] || [ $p = "-h" ]; then 79 usage faust2msp "[options] [Faust options] <file.dsp>" 80 require Max-MSP SDK 81 echo "Compiles Faust programs to Max6 externals using simple precision samples" 82 option 83 options -osc -midi -soundfile 84 option "-nvoices <num>" 85 option "-us <factor>" 86 option "-ds <factor>" 87 option "-filter <filter>" 88 option "-effect <effect.dsp>" 89 option -native "to compile for the native CPU (otherwise the 'generic' mode is used by default)" 90 option "Faust options" 91 exit 92 fi 93 94 if [ $p = "-nvoices" ]; then 95 shift 96 NVOICES=$1 97 if [ $NVOICES -ge 0 ]; then 98 CXXFLAGS="$CXXFLAGS -DNVOICES=$NVOICES" 99 fi 100 elif [ $p = "-effect" ]; then 101 POLYDEFS="-DPOLY2" 102 shift 103 EFFECT=$1 104 elif [ $p = "-midi" ]; then 105 MIDIDEFS="-DMIDICTRL" 106 elif [ $p = "-soundfile" ]; then 107 SOUNDFILE="1" 108 SOUNDFILEDEFS="-DSOUNDFILE" 109 SOUNDFILELIBS=`pkg-config --cflags --static --libs sndfile` 110 elif [ $p = "-osc" ]; then 111 OSCDEFS="-DOSCCTRL" 112 OSCLIBS="-lOSCFaust" 113 elif [ $p = "-native" ]; then 114 CXXFLAGS=$MYGCCFLAGS 115 elif [ $p = "-us" ]; then 116 shift 117 US=$1 118 elif [ $p = "-ds" ]; then 119 shift 120 DS=$1 121 elif [ $p = "-filter" ]; then 122 shift 123 FILTER=$1 124 elif [ ${p:0:1} = "-" ]; then 125 OPTIONS="$OPTIONS $p" 126 elif [[ -f "$p" ]] && [ ${p: -4} == ".dsp" ]; then 127 FILES="$FILES $p" 128 else 129 OPTIONS="$OPTIONS $p" 130 fi 131 132shift 133 134done 135 136#customize CXXFLAGS 137 138CXXFLAGS+=" -fbracket-depth=512" 139 140#------------------------------------------------------------------- 141# Check darwin specifics 142# 143if [[ $(uname) == Darwin ]]; then 144 EXT="~.mxo" 145fi 146 147#------------------------------------------------------------------- 148# compile the *.dsp files 149# 150PATH=$PATH:/usr/local/bin 151 152for p in $FILES; do 153 154 CC=g++ 155 156 CUR=$(pwd) 157 f=$(basename "$p") 158 SRCDIR=$(dirname "$p") 159 160 # creates a temporary dir 161 TDR=$(mktemp -d faust.XXXXXX) 162 TMP="$TDR/${f%.dsp}" 163 mkdir "$TMP" 164 165 # compile faust to c++ 166 if [ "$EFFECT" = "" ]; then 167 faust -i -cn ${f%.dsp} -uim -json -a $FAUSTARCH/max-msp/max-msp.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp" || exit 168 else 169 faust -i -cn ${f%.dsp} -uim -json -a $FAUSTARCH/max-msp/max-msp.cpp $OPTIONS "$SRCDIR/$f" -o "$TMP/${f%.dsp}.cpp" || exit 170 faust -i -cn effect -a $FAUSTARCH/minimal-effect.cpp "$SRCDIR/$EFFECT" -o "$TMP/effect.h" || exit 171 fi 172 173 # compile c++ to binary 174 ( 175 cd "$TMP" 176 install -d "${f%.dsp}$EXT/Contents/MacOS" 177 $CXX $CXXFLAGS -mmacosx-version-min=10.9 -Wfatal-errors -framework Carbon $POLYDEFS $MIDIDEFS $SOUNDFILEDEFS $OSCDEFS -DDOWN_SAMPLING=$DS -DUP_SAMPLING=$US -DFILTER_TYPE=$FILTER -I ../../ -I"$MAXINC" -I"$MSPINC" -F"$MAXINC" -F"$MSPINC" -framework MaxAPI -framework MaxAudioAPI $SOUNDFILELIBS $OSCLIBS -arch i386 -Wl,-Y,1455 -bundle "${f%.dsp}.cpp" -o "${f%.dsp}$EXT/Contents/MacOS/${f%.dsp}~" 178 ) >/dev/null || exit 179 180 rm -rf "$SRCDIR/${f%.dsp}$EXT" 181 182 # Keep .dsp and .cpp files in the plug-in 183 cp "$TMP/${f%.dsp}.cpp" "$TMP/${f%.dsp}$EXT" 184 cp "$SRCDIR/$f" "$TMP/${f%.dsp}$EXT" 185 # Create Info.plist 186 createInfoPList "${f%.dsp}~" "$TMP/${f%.dsp}$EXT/Contents/Info.plist" 187 188 if [ "$SOUNDFILE" = "1" ]; then 189 # get all soundfiles from the JSON file 190 cat $p.json | awk ' 191 BEGIN { FS=":"; SOFI=0; } 192 /"soundfile"/ { SOFI=1; } 193 /"url"/ { 194 if (SOFI) { 195 match($2, /"[^"]*/); 196 split(substr($2, RSTART+2, RLENGTH-3), res, ";"); 197 for (x in res) print substr(res[x], 2, length(res[x])-2); 198 SOFI=0; 199 } 200 } 201 ' > $p-tmp.txt 202 # copy found soundfiles in the final binary 203 for snd in $(cat $p-tmp.txt); do 204 if [ -f $snd ]; then 205 if [ ${snd:0:1} = "/" ]; then 206 echo "Warning: soundfile with absolute path is not copied !" 207 else 208 #create destination path and possibly create directory 209 sfpath="$TMP/${f%.dsp}$EXT/$(dirname $snd)/" 210 if ! [ -d $sfpath ]; then 211 echo "Create $sfpath" 212 mkdir $sfpath 213 fi 214 echo "Copy $snd in ${f%.dsp}$EXT" 215 cp $snd $sfpath 216 fi 217 else 218 echo "Error: file $snd not found !" 219 fi 220 done 221 rm $p-tmp.txt 222 fi 223 224 cp -r "$TMP/${f%.dsp}$EXT" "$SRCDIR/${f%.dsp}$EXT" 225 rm -rf "$TDR" 226 rm $p.json 227 228 # collect binary file name for FaustWorks 229 BINARIES="$BINARIES$SRCDIR/${f%.dsp}$EXT;" 230 231done 232 233BINARIES="$BINARIES ui.js" 234 235echo $BINARIES 236 237 238