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 @Christoph Hart
      last edited by

      @Christoph-Hart will be my homework then :( thanks mate

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

        @LightandSound A bit hard for me since it's needed to compile every time to see any changes. But I know it's super powerful

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

          @hisefilo said in Create Interfase on HISE to be used on JUCE:

          A bit hard for me since it's needed to compile every time to see any changes.

          Welcome to the slow world of "real" programming :p

          Always build debug while testing, it's much faster.

          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 thanks!!! see you there :P

            I'm really impressed with Faust simplicity. you can create a super complex DSP algorithm with just one line of code. If we are able to use HISE scripting and GUI power plus Faust...

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

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

              create a wrapper for the code around it and then compile HISE with the node.

              Any clue on how to wrap this simple one oscillator C++ example into a node??? Or any node-wrapping tutorial/example?

              /* ------------------------------------------------------------
              name: "sine"
              Code generated with Faust 2.23.8 (https://faust.grame.fr)
              Compilation options: -lang cpp -scal -ftz 0
              ------------------------------------------------------------ */
              
              #ifndef  __mydsp_H__
              #define  __mydsp_H__
              
              #ifndef FAUSTFLOAT
              #define FAUSTFLOAT float
              #endif 
              
              #include <algorithm>
              #include <cmath>
              #include <math.h>
              
              class mydspSIG0 {
              	
                private:
              	
              	int iRec0[2];
              	
                public:
              	
              	int getNumInputsmydspSIG0() {
              		return 0;
              	}
              	int getNumOutputsmydspSIG0() {
              		return 1;
              	}
              	int getInputRatemydspSIG0(int channel) {
              		int rate;
              		switch ((channel)) {
              			default: {
              				rate = -1;
              				break;
              			}
              		}
              		return rate;
              	}
              	int getOutputRatemydspSIG0(int channel) {
              		int rate;
              		switch ((channel)) {
              			case 0: {
              				rate = 0;
              				break;
              			}
              			default: {
              				rate = -1;
              				break;
              			}
              		}
              		return rate;
              	}
              	
              	void instanceInitmydspSIG0(int sample_rate) {
              		for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
              			iRec0[l0] = 0;
              		}
              	}
              	
              	void fillmydspSIG0(int count, float* table) {
              		for (int i = 0; (i < count); i = (i + 1)) {
              			iRec0[0] = (iRec0[1] + 1);
              			table[i] = std::sin((9.58738019e-05f * float((iRec0[0] + -1))));
              			iRec0[1] = iRec0[0];
              		}
              	}
              
              };
              
              static mydspSIG0* newmydspSIG0() { return (mydspSIG0*)new mydspSIG0(); }
              static void deletemydspSIG0(mydspSIG0* dsp) { delete dsp; }
              
              static float ftbl0mydspSIG0[65536];
              
              #ifndef FAUSTCLASS 
              #define FAUSTCLASS mydsp
              #endif
              
              #ifdef __APPLE__ 
              #define exp10f __exp10f
              #define exp10 __exp10
              #endif
              
              class mydsp : public dsp {
              	
               private:
              	
              	int fSampleRate;
              	float fConst0;
              	float fRec1[2];
              	
               public:
              	
              	void metadata(Meta* m) { 
              		m->declare("filename", "sine.dsp");
              		m->declare("math.lib/author", "GRAME");
              		m->declare("math.lib/copyright", "GRAME");
              		m->declare("math.lib/deprecated", "This library is deprecated and is not maintained anymore. It will be removed in August 2017.");
              		m->declare("math.lib/license", "LGPL with exception");
              		m->declare("math.lib/name", "Math Library");
              		m->declare("math.lib/version", "1.0");
              		m->declare("music.lib/author", "GRAME");
              		m->declare("music.lib/copyright", "GRAME");
              		m->declare("music.lib/deprecated", "This library is deprecated and is not maintained anymore. It will be removed in August 2017.");
              		m->declare("music.lib/license", "LGPL with exception");
              		m->declare("music.lib/name", "Music Library");
              		m->declare("music.lib/version", "1.0");
              		m->declare("name", "sine");
              	}
              
              	virtual int getNumInputs() {
              		return 0;
              	}
              	virtual int getNumOutputs() {
              		return 1;
              	}
              	virtual int getInputRate(int channel) {
              		int rate;
              		switch ((channel)) {
              			default: {
              				rate = -1;
              				break;
              			}
              		}
              		return rate;
              	}
              	virtual int getOutputRate(int channel) {
              		int rate;
              		switch ((channel)) {
              			case 0: {
              				rate = 1;
              				break;
              			}
              			default: {
              				rate = -1;
              				break;
              			}
              		}
              		return rate;
              	}
              	
              	static void classInit(int sample_rate) {
              		mydspSIG0* sig0 = newmydspSIG0();
              		sig0->instanceInitmydspSIG0(sample_rate);
              		sig0->fillmydspSIG0(65536, ftbl0mydspSIG0);
              		deletemydspSIG0(sig0);
              	}
              	
              	virtual void instanceConstants(int sample_rate) {
              		fSampleRate = sample_rate;
              		fConst0 = (440.0f / std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate))));
              	}
              	
              	virtual void instanceResetUserInterface() {
              	}
              	
              	virtual void instanceClear() {
              		for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
              			fRec1[l1] = 0.0f;
              		}
              	}
              	
              	virtual void init(int sample_rate) {
              		classInit(sample_rate);
              		instanceInit(sample_rate);
              	}
              	virtual void instanceInit(int sample_rate) {
              		instanceConstants(sample_rate);
              		instanceResetUserInterface();
              		instanceClear();
              	}
              	
              	virtual mydsp* clone() {
              		return new mydsp();
              	}
              	
              	virtual int getSampleRate() {
              		return fSampleRate;
              	}
              	
              	virtual void buildUserInterface(UI* ui_interface) {
              		ui_interface->openVerticalBox("sine");
              		ui_interface->closeBox();
              	}
              	
              	virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
              		FAUSTFLOAT* output0 = outputs[0];
              		for (int i = 0; (i < count); i = (i + 1)) {
              			fRec1[0] = (fConst0 + (fRec1[1] - std::floor((fConst0 + fRec1[1]))));
              			output0[i] = FAUSTFLOAT(ftbl0mydspSIG0[int((65536.0f * fRec1[0]))]);
              			fRec1[1] = fRec1[0];
              		}
              	}
              
              };
              
              #endif
              
              
              1 Reply Last reply Reply Quote 0
              • Dan KorneffD
                Dan Korneff
                last edited by

                @hisefilo A couple years back, Christoph suggested I look at his MDA effect wrapper for inspiration.
                check out

                HISE-scriptnode\hi_modules\effects
                

                Dan Korneff - Producer / Mixer / Audio Nerd

                hisefiloH 1 Reply Last reply Reply Quote 0
                • 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
                                            • First post
                                              Last post

                                            17

                                            Online

                                            1.7k

                                            Users

                                            11.9k

                                            Topics

                                            103.2k

                                            Posts