HISE Logo Forum
    • Categories
    • Register
    • Login

    Create Interfase on HISE to be used on JUCE

    Scheduled Pinned Locked Moved General Questions
    32 Posts 6 Posters 2.3k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • hisefiloH
      hisefilo @Dan Korneff
      last edited by

      @dustbro thanks mate!! will take a look (C++ still being a pain for me)

      1 Reply Last reply Reply Quote 0
      • Christoph HartC
        Christoph Hart
        last edited by

        Hmm, I think it's a little bit over your head to make a proper wrapper for that code (also I think I need to tinker with the compiler flags to see if I can change the code a little bit as there are a few annoying things in it). The most promising solution would be if I just create a wrapper node for faust code that you then can use.

        hisefiloH Dan KorneffD 2 Replies Last reply Reply Quote 3
        • hisefiloH
          hisefilo @Christoph Hart
          last edited by hisefilo

          @Christoph-Hart said in Create Interfase on HISE to be used on JUCE:

          The most promising solution would be if I just create a wrapper node for faust code that you then can use.

          That would be awesome and a way to many faust users to get into HISE (Faust lacks of GUI designer)

          JOS will be so happy if that happens :)
          This is the faust2juce script if it helps

          #! /bin/bash -e
          
          #####################################################################
          #                                                                   #
          #           Compiles Faust programs to JUCE standalone or plugin    #
          #           (c) Grame, 2016-2019                                    #
          #                                                                   #
          #####################################################################
          
          . faustpath
          . faustoptflags
          . usage.sh
          
          CXXFLAGS=$MYGCCFLAGS
          
          DEBUG=false
          
          #-------------------------------------------------------------------
          #PHASE 1 : dispatch command arguments
          #-------------------------------------------------------------------
          
          OSCLIB=""
          POLY="POLY"
          DEF=""
          EFFECT=""
          NVOICES=-1
          STANDALONE="0"
          IS_SYNTH="0"
          IS_MIDI="0"
          IS_LLVM="0"
          JUCE_POLY="0"
          FAUSTFLOAT="float"
          JUCER=""
          JUCE_MODULES_DIR="\.\.\/\.\.\/modules"  # By default, the generated folder is supposed to be copied in JUCE/examples folder
          
          while [ $1 ]
          do
              p=$1
          
              if [ $p = "--help" ] || [ $p = "-help" ] || [ $p = "-h" ]; then
                  usage faust2juce "[options] [Faust options] <file.dsp>"
                  require Juce 
                  echo "Compiles Faust programs to JUCE standalone or plugin."
                  option
                  options -osc -midi -soundfile
                  option "-nvoices <num>"
                  option "-effect <effect.dsp>"
                  option "-effect auto"
                  option -standalone "to produce a standalone project, otherwise a plugin project is generated"
                  option -"jucemodulesdir <folder>" "to set JUCE modules directory to <folder>, such as ~/JUCE/modules"
                  option -jsynth "to use JUCE polyphonic Synthesizer instead of Faust polyphonic code"
                  option -llvm "to use the LLVM compilation chain (OSX and Linux for now)"
                  exit
              fi
          
              if [ "$p" = -debug ]; then
              	DEBUG=true
              elif [ $p = "-nvoices" ]; then
                  shift
                  NVOICES=$1
              elif [ $p = "-standalone" ]; then
                  STANDALONE="1"
              elif [ $p = "-effect" ]; then
                  DEF+="POLY2 "
                  POLY="POLY2"
                  shift
                  EFFECT=$1
              elif [ $p = "-jucemodulesdir" ]; then
          	    shift
          	    JUCE_MODULES_DIR=$(echo $1 | sed -e 's/\//\\\//g')
              elif [ $p = "-jsynth" ]; then
                  DEF+="JUCE_POLY "
                  JUCE_POLY="1"
              elif [ $p = "-midi" ]; then
                  DEF+="MIDICTRL "
                  IS_MIDI="1"
              elif [ $p = "-osc" ]; then
              	DEF+="OSCCTRL "
          	elif [ $p = "-llvm" ]; then
          		IS_LLVM="1"
              elif [ $p = "-soundfile" ]; then
                  DEF+="SOUNDFILE "
              elif [ ${p:0:1} = "-" ]; then
                  if [ $p = "-double" ]; then
                      FAUSTFLOAT="double"
                  fi
          	    OPTIONS="$OPTIONS $p"
          	elif [[ -f "$p" ]]; then
          	    FILES="$FILES $p"
          	else
          	    OPTIONS="$OPTIONS $p"        
          	fi
          
          shift
          
          done
          
          # configure JUCER file
          
          if [ $STANDALONE = "1" ]; then
              if [ $IS_LLVM = "1" ]; then
                  JUCER="standalone-llvm.jucer"
              else
                  JUCER="standalone.jucer"
              fi
          else
              if [ $IS_LLVM = "1" ]; then
                  JUCER="plugin-llvm.jucer"
              else
                  JUCER="plugin.jucer"
              fi
          fi
          
          if [ $STANDALONE = "1" ] && [ $JUCE_POLY = "1" ]; then
              echo "Cannot use -standalone with -jsynth"
              exit
          fi
          
          if [ $POLY = "POLY2" ] && [ $JUCE_POLY = "1" ]; then
              echo "Cannot use -effect with -jsynth"
              exit
          fi
          
          #look for polyphonic "nvoices" metadata in the DSP file
          
          grep "declare nvoices" $FILES && IS_SYNTH="1" 2>/dev/null
          
          #-------------------------------------------------------------------
          # compile the *.dsp files
          #-------------------------------------------------------------------
          
          for p in $FILES; do
          
              CUR=$(pwd)
              f=$(basename "$p")
          	SRCDIR=$(dirname "$p")
          
              # creates the dir 
              dspName="${f%.dsp}"
              SUB_TYPE=$(shasum $p)
              SUB_TYPE=${SUB_TYPE:0:4}
              rm -rf "$SRCDIR/$dspName"
           
              if [ $STANDALONE = "0" ]; then
                  cp -r $FAUSTARCH/juce/plugin "$SRCDIR/$dspName/"
                  # setting plugin name to match the dsp
                  sed -e "s/SUB_TYPE/$SUB_TYPE/g" "$SRCDIR/$dspName/$JUCER" >> "$SRCDIR/$dspName/$dspName-temp.jucer"
              else
                  cp -r $FAUSTARCH/juce/standalone "$SRCDIR/$dspName/"
                  # setting project name to match the dsp
                  sed -e "s/ProjectTitle/$dspName/g" "$SRCDIR/$dspName/$JUCER" >> "$SRCDIR/$dspName/$dspName-temp.jucer"
              fi
          
              # setting the preprocessing definitions
              sed -e "s/PreProcDef/$DEF/g" "$SRCDIR/$dspName/$dspName-temp.jucer" >> "$SRCDIR/$dspName/$dspName-temp0.jucer"
              sed -e "s/APPL_NAME/$dspName/g" "$SRCDIR/$dspName/$dspName-temp0.jucer" >> "$SRCDIR/$dspName/$dspName-temp1.jucer"
          
              # MIDI
              sed -e "s/IS_MIDI/$IS_MIDI/g" "$SRCDIR/$dspName/$dspName-temp1.jucer" >> "$SRCDIR/$dspName/$dspName-temp2.jucer"
          
              # SYNTH
              sed -e "s/IS_SYNTH/$IS_SYNTH/g" "$SRCDIR/$dspName/$dspName-temp2.jucer" >> "$SRCDIR/$dspName/$dspName-temp3.jucer"
          
              # FAUSTFLOAT
              sed -e "s/FAUST_FLOAT/$FAUSTFLOAT/g" "$SRCDIR/$dspName/$dspName-temp3.jucer" >> "$SRCDIR/$dspName/$dspName-temp4.jucer"
          
              # JUCE_MODULES_DIR
              sed -e "s/JUCE_MODULES_DIR_DEFAULT/$JUCE_MODULES_DIR/g" "$SRCDIR/$dspName/$dspName-temp4.jucer" >> "$SRCDIR/$dspName/$dspName-temp5.jucer"
          
              # possibly set NVOICES value
              if [ $NVOICES -ge 0 ]; then
                  sed -e "s/NUM_VOICES/$NVOICES/g" "$SRCDIR/$dspName/$dspName-temp5.jucer" >> "$SRCDIR/$dspName/$dspName.jucer"
              else
                  cp "$SRCDIR/$dspName/$dspName-temp5.jucer" "$SRCDIR/$dspName/$dspName.jucer"
              fi
          
              # standalone or plugin mode
              if [ $STANDALONE = "0" ]; then
                  rm "$SRCDIR/$dspName/plugin-llvm.jucer" "$SRCDIR/$dspName/plugin.jucer"
              else
                  rm "$SRCDIR/$dspName/standalone-llvm.jucer" "$SRCDIR/$dspName/standalone.jucer"
              fi
            
              rm "$SRCDIR/$dspName/$dspName-temp.jucer"  "$SRCDIR/$dspName/$dspName-temp0.jucer" 
              rm "$SRCDIR/$dspName/$dspName-temp1.jucer" "$SRCDIR/$dspName/$dspName-temp2.jucer"
              rm "$SRCDIR/$dspName/$dspName-temp3.jucer" "$SRCDIR/$dspName/$dspName-temp4.jucer" 
              rm "$SRCDIR/$dspName/$dspName-temp5.jucer"
          
              # standalone of plugin mode
              if [ $STANDALONE = "0" ]; then
                  if [ $IS_LLVM = "1" ]; then
                      faust -inj $FAUSTINC/faust/dsp/llvm-dsp-adapter.h -uim -i -a $FAUSTARCH/juce/juce-plugin.cpp $OPTIONS "$SRCDIR/$f" -o "$SRCDIR/$dspName/FaustPluginProcessor.cpp" || exit
                      dynamic-faust $OPTIONS "$SRCDIR/$f" -o "$SRCDIR/$dspName/dynamic.o"
                  else
                      faust -uim -i -a $FAUSTARCH/juce/juce-plugin.cpp $OPTIONS "$SRCDIR/$f" -o "$SRCDIR/$dspName/FaustPluginProcessor.cpp" || exit
                  fi
              else
                  if [ $IS_LLVM = "1" ]; then
                      faust -inj $FAUSTINC/faust/dsp/llvm-dsp-adapter.h -i -a $FAUSTARCH/juce/juce-standalone.cpp $OPTIONS "$SRCDIR/$f" -o "$SRCDIR/$dspName/FaustAudioApplication.cpp" || exit
                      dynamic-faust $OPTIONS "$SRCDIR/$f" -o "$SRCDIR/$dspName/dynamic.o"
                  else
                      faust -i -a $FAUSTARCH/juce/juce-standalone.cpp $OPTIONS "$SRCDIR/$f" -o "$SRCDIR/$dspName/FaustAudioApplication.cpp" || exit
                  fi
              fi
          
              if [ $POLY = "POLY2" ]; then
                  if [ $EFFECT = "auto" ]; then
                      cat > $SRCDIR/$dspName/effect.dsp << EndOfCode
                      adapt(1,1) = _;
                      adapt(2,2) = _,_;
                      adapt(1,2) = _ <: _,_;
                      adapt(2,1) = _,_ :> _;
                      adaptor(F,G) = adapt(outputs(F),inputs(G));
                      process = adaptor(library("$SRCDIR/$f").process, library("$SRCDIR/$f").effect) : library("$SRCDIR/$f").effect;
          EndOfCode
                      faust -i -cn effect -a minimal-effect.cpp "$SRCDIR/$dspName/effect.dsp" -o "$SRCDIR/$dspName/effect.h" || exit
                      rm "$SRCDIR/$dspName/effect.dsp"
                  else
                      faust -i -cn effect -a minimal-effect.cpp "$SRCDIR/$EFFECT" -o "$SRCDIR/$dspName/effect.h" || exit
                  fi
              fi
          
          done
          
          
          ustkU 1 Reply Last reply Reply Quote 0
          • ustkU
            ustk @hisefilo
            last edited by ustk

            @hisefilo Just to understand, what is the benefit of using Faust?
            For what I see, everything can be made directly with scriptnode/snex right? 🤔
            Easier than snex maybe?

            Can't help pressing F5 in the forum...

            d.healeyD hisefiloH 2 Replies Last reply Reply Quote 0
            • d.healeyD
              d.healey @ustk
              last edited by d.healey

              @ustk Faust is less buggy :p

              But I've stopped playing with Faust for now because I'd rather use the new (less buggy?) version of SNEX when it's ready.

              Libre Wave - Freedom respecting instruments and effects
              My Patreon - HISE tutorials
              YouTube Channel - Public HISE tutorials

              hisefiloH 1 Reply Last reply Reply Quote 1
              • hisefiloH
                hisefilo @ustk
                last edited by

                @ustk it's being developed for years and a huge library is there (Many of them developed by JOS)
                i.e. you may have an analog modelled filter in just a few lines of code

                Link Preview Image
                Faust Programming Language

                favicon

                (faust.grame.fr)

                1 Reply Last reply Reply Quote 0
                • hisefiloH
                  hisefilo @d.healey
                  last edited by hisefilo

                  @d-healey I haven't realised yet what SNEX will allow me to do. C++ is kinda obscure zone for me.

                  Faust does the compile thing to turn this one line thingy into a physically modelled trumpet on C++

                  process = pm.trumpet <: _,_; 
                  
                  d.healeyD 1 Reply Last reply Reply Quote 0
                  • Dan KorneffD
                    Dan Korneff @Christoph Hart
                    last edited by

                    @Christoph-Hart said in Create Interfase on HISE to be used on JUCE:

                    The most promising solution would be if I just create a wrapper node for faust code that you then can use.

                    Maybe one for my Matlab models too? ;)

                    Dan Korneff - Producer / Mixer / Audio Nerd

                    1 Reply Last reply Reply Quote 1
                    • d.healeyD
                      d.healey @hisefilo
                      last edited by

                      @hisefilo I played around with those physical models, that particular function though is just a wrapper around the STK. It's good for demonstration but you don't have any control over the components.

                      I rebuilt the Faust pm.flute inside Faust so that I could control each element and change the bits I didn't like, it wasn't one line :p I want to rebuild it in HISE at some point.

                      Libre Wave - Freedom respecting instruments and effects
                      My Patreon - HISE tutorials
                      YouTube Channel - Public HISE tutorials

                      hisefiloH 1 Reply Last reply Reply Quote 0
                      • hisefiloH
                        hisefilo @d.healey
                        last edited by

                        @d-healey said in Create Interfase on HISE to be used on JUCE:

                        I want to rebuild it in HISE at some point.

                        Yeah, me too.

                        hisefiloH 1 Reply Last reply Reply Quote 0
                        • hisefiloH
                          hisefilo @hisefilo
                          last edited by

                          @d-healey Do you know if SNEX will require C++ knowledge for creating custom stuff?? Like an Karplus-Strong modified algo or an oscillator able to read data tables?

                          d.healeyD 1 Reply Last reply Reply Quote 0
                          • d.healeyD
                            d.healey @hisefilo
                            last edited by

                            @hisefilo https://docs.hise.audio/scriptnode/manual/snex.html

                            Libre Wave - Freedom respecting instruments and effects
                            My Patreon - HISE tutorials
                            YouTube Channel - Public HISE tutorials

                            hisefiloH 1 Reply Last reply Reply Quote 0
                            • hisefiloH
                              hisefilo @d.healey
                              last edited by

                              @d-healey said in Create Interfase on HISE to be used on JUCE:

                              @hisefilo https://docs.hise.audio/scriptnode/manual/snex.html

                              Yes, being there. Needs a lot of C++ skills

                              d.healeyD 1 Reply Last reply Reply Quote 0
                              • d.healeyD
                                d.healey @hisefilo
                                last edited by d.healey

                                @hisefilo It's very simplified though, doesn't look much worse than Javascript

                                for(auto& sample: block)
                                {
                                    sample = (float)Math.sin(uptime);
                                    uptime += 0.002;
                                }
                                

                                The only bit there I don't really understand is auto& but I'm sure it's not too tricky to figure out.

                                Libre Wave - Freedom respecting instruments and effects
                                My Patreon - HISE tutorials
                                YouTube Channel - Public HISE tutorials

                                1 Reply Last reply Reply Quote 0
                                • Christoph HartC
                                  Christoph Hart
                                  last edited by Christoph Hart

                                  This doc is slightly outdated as there have been many additions to SNEX. Basically SNEX is C++ minus all stuff that you don't need for DSP:

                                  • String operations (there's even not a text data type)
                                  • File I/O or other OS stuff
                                  • inheritance and constructor / destructors of objects
                                  • pointer syntax, so any reference to memory is being done via the reference operator &. I chose to do this because it's much harder to create a null reference using this approach which makes the language a bit more stable (especially in a prototyping context).

                                  However I would say that it's halfway between HiseScript and C++. Sure you have to use proper typing (in HiseScript / Javascript it doesn't matter if a number is a integer or floating point number, but since SNEX directly creates machine code, it needs strict typing to emit the correct assembly.

                                  var x = 12 + 0.5; // OK in HiseScript
                                  float x = 12 + 0.5; // type mismatch, will print a warning and cast implicitely to float.
                                  

                                  The example that David posted is trivially portable to HiseScript:

                                  for(auto& sample: block)
                                  {
                                      sample = (float)Math.sin(uptime);
                                      uptime += 0.002;
                                  }
                                  
                                  // in HiseScript:
                                  
                                  for(sample in block)
                                  {
                                      sample = Math.sin(uptime);
                                      uptime += 0.002;
                                  }
                                  

                                  The Math class is almost 100% identical in SNEX and HiseScript so this eases the pain a bit :)
                                  About the auto&: In SNEX you have the same range-based for loop as in Javascript (give it an array and it will iterate from the start to the end). However since it's strictly typed, you need to declare the element type of the block array that you want to iterate. auto is just a way of letting the compiler figure out the type itself, so it removes redundancy:

                                  auto x = 12; // x is an int;
                                  int x = 12;  // same statement but you have to figure out the type yourself.
                                  
                                  auto y = 12.0f; // x is a float (the f postfix indicates single precision)
                                  

                                  Now the & operator means "reference to" and tells the compiler to operate on the oringal data itself. Outside a loop it can be used like this:

                                  int x = 126;
                                  auto& refX = x;
                                  
                                  refX = 100; // x is also 100 now
                                  
                                  auto noRef = x; // omit the & makes a copy
                                  noRef = 9000; // is still 100
                                  

                                  Now if you write the loop without the & like this:

                                  for(auto sample: block)
                                  {
                                      sample = (float)Math.sin(uptime);
                                      uptime += 0.002;
                                  }
                                  

                                  it is still valid C++ / SNEX syntax, but it will not have an effect because the sample variable will not point to the actual element in the array, but a copy of the value (like noRef in the example above), so the sine wave is being rendered into nirvana.

                                  hisefiloH 1 Reply Last reply Reply Quote 3
                                  • hisefiloH
                                    hisefilo @Christoph Hart
                                    last edited by

                                    @Christoph-Hart Thanks you!!!!!

                                    well! I guess I started learning SNEX now!
                                    I'm on January Scriptnode. Should I find a new working commit ? (MacOS)

                                    d.healeyD 1 Reply Last reply Reply Quote 0
                                    • d.healeyD
                                      d.healey @hisefilo
                                      last edited by

                                      @hisefilo Wait for HISE 3 :D

                                      Libre Wave - Freedom respecting instruments and effects
                                      My Patreon - HISE tutorials
                                      YouTube Channel - Public HISE tutorials

                                      1 Reply Last reply Reply Quote 0
                                      • Christoph HartC
                                        Christoph Hart
                                        last edited by

                                        Yeah I can‘t recommend diving into SNEX at the moment (especially on macOS), I‘m afraid you need to wait a few more weeks.

                                        hisefiloH 1 Reply Last reply Reply Quote 0
                                        • hisefiloH
                                          hisefilo @Christoph Hart
                                          last edited by

                                          @Christoph-Hart @d-healey already diving into (yeah I'm that anxious) . I need to solve a DSP thingy some how... so I will adapt it later to the new SNEX I guess.

                                          I'm sketching in Faust, and trying to reproduce that on SNEX....

                                          1 Reply Last reply Reply Quote 1
                                          • First post
                                            Last post

                                          19

                                          Online

                                          1.7k

                                          Users

                                          11.9k

                                          Topics

                                          103.2k

                                          Posts