HISE Logo Forum
    • Categories
    • Register
    • Login

    Multiple instruments, single project or multiple projects?

    Scheduled Pinned Locked Moved General Questions
    94 Posts 3 Posters 22.2k 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.
    • Christoph HartC
      Christoph Hart
      last edited by

      I think a filename string with (or without) an extension. it will write it in the user presets folder.

      You need to use semantic versioning for your project in order to use user presets. The reason is that then you'll be able to bump the patch version number a.b.x without having this popup appear (which is annoying for small bug fixes). If you add new controls, bump the minor version number a.x.c and it will add default values of those new controls when you press OK there.

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

        I think I'm misunderstanding something
        alt text

        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

          You need a patch version number. 1.0.0 will do :)

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

            Ah and you don't need to specify the version number in the filename of the preset, it will be stored inside the XML itself (using the current Project Version Number)

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

              This is a preset I created in the preset browser not in the script that is causing this popup

              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

                The preset has probably still the old wrong version 1.0 baked in. You can edit the .preset file (it's just an ordinary XML file) and correct the version number manually.

                But I'll add a safe check that you have a valid semantic version syntax in your Project Version before creating the first preset to avoid this in the future...

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

                  Do you mean the .hip preset or the user preset? That might be where I'm getting confused

                  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

                    .preset is the file extension for user presets (=collection of front end interface values). The .hip preset (NOT a preset, poor name, bad decision :) doesn't store the version value (only the Build Version of HISE), because it doesn't need it as it can get that info easily from the Project Setting file, while the .preset files are supposed to be distributed along with the plugin and don't have that kind of privilege :)

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

                      Ok that's what I thought. Then I'm still confused, thank you for your patience :)

                      I made a brand new project folder, inserted a script processor, put in one command Content.makeFrontInterface(600, 250); compiled it. Then I opened the plugin preview and went to the preset browser, created a preset and then when I try to load that preset by clicking on it I get the version number error. This hasn't happened to me previously. I can make a little video if it helps.

                      Update:
                      So I opened the preset file in sublime text and the version was set to 0.0. I changed this to 1.0.0. I tried opening it in the preset browser again and I got the same error (it said version 1.0.0 this time though). I click Ok to update it and it resets it back to 0.0. So I think there is a bug here.

                      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

                        have you set the Project Version at File Setting Project Setting?

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

                          Aha! mystery solved. Nope I hadn't set that, never have, I will from now on :) thanks again.

                          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

                            This is important as it will also show up as version of the compiled app / plugin. I'll add a safe check that requires to set this before exporting.

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

                              Excellent, that will help newbies like me :p

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

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

                                I've got this test project with 2 script processors:

                                <?xml version="1.0" encoding="UTF-8"?>
                                
                                <Processor Type="SynthChain" ID="Master Chain" Bypassed="0" Gain="1" Balance="0"
                                           VoiceLimit="64" KillFadeTime="20" IconColour="0" packageName=""
                                           views="32.rk1bzA........JPT.............+Oe7wG+SA...." currentView="-1">
                                  <EditorStates BodyShown="0" Visible="1" Solo="0" InterfaceShown="0"/>
                                  <ChildProcessors>
                                    <Processor Type="MidiProcessorChain" ID="Midi Processor" Bypassed="0">
                                      <EditorStates BodyShown="1" Visible="1" Solo="0" Folded="0"/>
                                      <ChildProcessors>
                                        <Processor Type="ScriptProcessor" ID="Script Processor" Bypassed="0" Script="Content.makeFrontInterface(600, 200);&#13;&#10;&#13;&#10;const var knob = Content.addKnob(&quot;knob&quot;, 0, 0);function onNoteOn()&#10;{&#10;&#9;&#10;}&#10;function onNoteOff()&#10;{&#10;&#9;&#10;}&#10;function onController()&#10;{&#10;&#9;&#10;}&#10;function onTimer()&#10;{&#10;&#9;&#10;}&#10;function onControl(number, value)&#10;{&#10;&#9;&#10;}&#10;">
                                          <EditorStates BodyShown="1" Visible="1" Solo="0" contentShown="1" onInitOpen="0"
                                                        onNoteOnOpen="0" onNoteOffOpen="0" onControllerOpen="0" onTimerOpen="0"
                                                        onControlOpen="0"/>
                                          <ChildProcessors/>
                                          <Content>
                                            <Control type="ScriptSlider" id="knob" value="0.46000001"/>
                                          </Content>
                                        </Processor>
                                        <Processor Type="ScriptProcessor" ID="Script Processor2" Bypassed="0" Script="&#10;const var knob = Content.addKnob(&quot;knob1&quot;, 0, 0);&#10;const button = Content.addButton(&quot;Save Preset&quot;, 150, 10);&#10;&#10;//CALLBACKS&#10;function onNoteOn()&#10;{&#10;&#9;&#10;}&#10;function onNoteOff()&#10;{&#10;&#9;&#10;}&#10;function onController()&#10;{&#10;&#9;&#10;}&#10;function onTimer()&#10;{&#10;&#9;&#10;}&#10;function onControl(number, value)&#10;{&#10;&#9;if (number == button)&#10;&#9;{&#10;&#9;&#9;Content.storeAllControlsAsPreset(&quot;Test Bank/Test Category/Another Test.preset&quot;, &quot;&quot;);&#10;&#9;}&#10;}">
                                          <EditorStates BodyShown="1" Visible="1" Solo="0" contentShown="1" onInitOpen="1"
                                                        onNoteOnOpen="0" onNoteOffOpen="0" onControllerOpen="0" onTimerOpen="0"
                                                        onControlOpen="0"/>
                                          <ChildProcessors/>
                                          <Content>
                                            <Control type="ScriptSlider" id="knob1" value="0"/>
                                            <Control type="ScriptButton" id="Save Preset" value="1"/>
                                          </Content>
                                        </Processor>
                                      </ChildProcessors>
                                    </Processor>
                                    <Processor Type="ModulatorChain" ID="GainModulation" Bypassed="0" Intensity="1">
                                      <EditorStates BodyShown="1" Visible="0" Solo="0" Folded="1"/>
                                      <ChildProcessors/>
                                    </Processor>
                                    <Processor Type="ModulatorChain" ID="PitchModulation" Bypassed="1" Intensity="0">
                                      <EditorStates BodyShown="1" Visible="0" Solo="0" Folded="1"/>
                                      <ChildProcessors/>
                                    </Processor>
                                    <Processor Type="EffectChain" ID="FX" Bypassed="0">
                                      <EditorStates BodyShown="1" Visible="0" Solo="0" Folded="1"/>
                                      <ChildProcessors/>
                                    </Processor>
                                  </ChildProcessors>
                                  <RoutingMatrix NumSourceChannels="2" Channel0="0" Send0="-1" Channel1="1" Send1="-1"/>
                                  <macro_controls>
                                    <macro name="Macro 1" value="0" midi_cc="-1"/>
                                    <macro name="Macro 2" value="0" midi_cc="-1"/>
                                    <macro name="Macro 3" value="0" midi_cc="-1"/>
                                    <macro name="Macro 4" value="0" midi_cc="-1"/>
                                    <macro name="Macro 5" value="0" midi_cc="-1"/>
                                    <macro name="Macro 6" value="0" midi_cc="-1"/>
                                    <macro name="Macro 7" value="0" midi_cc="-1"/>
                                    <macro name="Macro 8" value="0" midi_cc="-1"/>
                                  </macro_controls>
                                  <MidiAutomation/>
                                </Processor>
                                

                                I've got this preset

                                <?xml version="1.0" encoding="UTF-8"?>
                                
                                <Preset Version="1.0.0">
                                  <Content Processor="Script Processor2">
                                    <Control type="ScriptSlider" id="knob1" value="0.63"/>
                                    <Control type="ScriptButton" id="Save Preset" value="1"/>
                                  </Content>
                                  <MidiAutomation/>
                                </Preset>
                                

                                But it doesn't do anything when I load it. It seems presets will only affect script 1 which is set to frontInterface.

                                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, as I said, it just supports one front interface.

                                  Check out this example:

                                  0_1488794377602_Preset Example.zip

                                  The second Script Processor is no front interface. Instead it uses a global object that contains the value for its knob which will be restored by the main interfaces' onControl callback.

                                  This is a little bit complicated at first, but once you understand how it's connected, its a pretty easy procedure.

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

                                    Aha I get it now, thank you! It seems a little awkward though if you have a lot of scripts (like I do) and want to save the state of most of the controls in the preset. Can users overwrite or delete factory presets after the plugin has been compiled?

                                    Edit: Just reread the blog post about these being read-only :)

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

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

                                      I'm struggling to find an efficient way to organise my preset handling script. I can see this being more suited to smaller instruments.

                                      So I have my woowind .hip file and I'd like the user to be able to change between all of the different woodwind instruments. There will be at least 10 instruments and each one will have 10 or more samplers that will need to have their sample maps swapped as the preset is selected. Each will also need it's key range setting, modulator settings adjusted, and various behind-the-scenes knobs adjusted on scripts.

                                      To hardcode all of this seems a very large task. I could add code to each script so that its values are stored in the userPresetData globals object (although it would be better if HISE did this anyway I think). But I will still have to write all of the sample maps into code, and if I want to add new sample maps I will have to edit the code again. Is there a more generic and automated way to populate the userPresetData object?

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

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

                                        What I'm finding is that by using the global user_preset_array idea I'm essentially building my own preset system for the instrument that works independently of the actual HISE preset system which seems a bit backwards to me. The only purpose of the HISE preset system becomes to change a combo box value. Is there no way the preset system could just take a snapshot of all of the controls, loaded sample maps, and the bypass state of samplers/modulators/etc. and then restore it when the preset is selected? This seems far more practical in the long term than having to construct this functionality individually for each instrument.

                                        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

                                          I'll have to disagree with you here. The idea of the preset system is to store snapshots of the main interface so that it recalls the controls. If your library allows to select different instruments that swap out multiple sample maps and adjust modulators and key ranges, then this is something you have to add to a combobox anyway.

                                          On the other hand, adding support for changing modulators behind the scenes or swapping out sample maps for samplers directly opens up a parallel world which is disconnected from the main interface - do you get what I mean?

                                          You might be able to reduce the complexity by generating the sample map IDs dynamically (which requires a consistent naming, but we'll agree that this is good to have anyway). Let's say you have :

                                          • a trombone
                                          • a trumpet
                                          • a flute
                                          • a clarinet

                                          and each instrument uses sustain, release, staccato and portato samples.

                                          then you could do something like this:

                                          const var instrumentNames = ["Trombone", "Trumpet", "Flute", "Clarinet"];
                                          const var articulations = ["Sustain", "Release", "Staccato", "Portato"];
                                          const var hasPortato = [true, true, false, true];
                                          const var keyRanges = [[40, 80], [43, 80], [56, 90], [50, 93]];
                                          
                                          sustainSampler = Synth.getSampler( articulations[0]);
                                          releaseSampler = Synth.getSampler( articulations[1]);
                                          staccatoSampler = Synth.getSampler(articulations[2]);
                                          portatoSampler = Synth.getSampler( articulations[3]);
                                          
                                          
                                          inline function loadInstrument(i)
                                          {
                                              sustainSampler.loadSampleMap(instrumentNames[i] + "_" + articulations[0]);
                                              releaseSampler.loadSampleMap(instrumentNames[i] + "_" + articulations[1]);
                                              staccatoSampler.loadSampleMap(instrumentNames[i] + "_" + articulations[2]);
                                              portatoSampler.loadSampleMap(instrumentNames[i] + "_" + articulations[3]);
                                          
                                              portatoSampler.setBypassed(!hasPortato[i]);
                                              changeKeyRange(i);
                                          };
                                          
                                          inline function changeKeyRange(i)
                                          {
                                               // set the key colours for the given range in keyRanges[i]
                                          }
                                          
                                          

                                          In the onControl callback of the combobox you just have to call loadInstrument(value). The amount of needed strings is reduced from 16 to 8 here (and in your actual use case it would be 100 Strings vs. 20). Also, this collects all information into nicely readable arrays at the beginning of your script.

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

                                            Thanks, this makes it look a bit simpler and gives me an idea. I don't like having to hard code the sample map names, but what I'm thinking is if I gave the sample maps the same names as the containers and or samplers that they are to be used in then that would allow the .hip to be used for more instruments without having to keep editing the code. I could just read from the various module names.

                                            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

                                            43

                                            Online

                                            1.7k

                                            Users

                                            11.7k

                                            Topics

                                            101.9k

                                            Posts