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 3.1k 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.

          Free HISE Bootcamp Full Course for beginners.
          YouTube Channel - Public HISE tutorials
          My Patreon - 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?

                        Hise made me an F5 dude, browser just suffers...

                        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.

                          Free HISE Bootcamp Full Course for beginners.
                          YouTube Channel - Public HISE tutorials
                          My Patreon - 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

                            https://faust.grame.fr/tools/playground/index.html

                            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.

                                  Free HISE Bootcamp Full Course for beginners.
                                  YouTube Channel - Public HISE tutorials
                                  My Patreon - 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

                                        Free HISE Bootcamp Full Course for beginners.
                                        YouTube Channel - Public HISE tutorials
                                        My Patreon - 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.

                                            Free HISE Bootcamp Full Course for beginners.
                                            YouTube Channel - Public HISE tutorials
                                            My Patreon - HISE tutorials

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

                                            13

                                            Online

                                            2.0k

                                            Users

                                            12.6k

                                            Topics

                                            109.8k

                                            Posts