The tree hierarchy is the most important difference between HISE and KONTAKT and I chose this data structure because it allows encapsulation of logic that can be never done with a flat list like the group structure of KONTAKT.
Sample Libraries consist of many different types of samples - the most popular being sustain samples, release samples and legato samples. Throwing them all into one big bucket and then trying to adress these types within the big melting pot of groups screams for needless boilerplate scripting code:
disallow_group($ALL_GROUPS)
allow_group(1,3,6)
// do some random stuff here
allow_group($ALL_GROUPS)
I remember writing this type of script code all over the place - before I decided to roll my own sampler
This is because when KONTAKT and their core design was developed, sample libraries weren't that big (legato transitions were the absolute exception and most libraries didn't even had release trigger samples). But thanks to KONTAKT (got to give them that - the sample library technology emerged pretty quickly and I think KONTAKT got overrun by its users.
So now we have the chance to look at today's requirements for sample libraries (and with Elan's phaselocking stuff maybe also about tomorrows requirements) and build a system which has these principles as core organization logic.
@167ixo55:
This confuses me even more. So three separate scripts for three separate types of samples? Again, the samples can be triggered in totally different contexts, and all in a single note-on event. Very often how each sample type is triggered and processed depends on shared data related to note and release events. Splitting that up into three separate scripts sounds like an absolute nightmare and I would never do it.
For me this is the opposite of an absolute nightmare. The ability to write small, highly specified scripts (which sometime consist of only a few lines of code) allows developer-friendly workflows like encapsulation and can be far easier debugged and maintained than the muliple thousand line monster scripts in KSP.
We are not talking about having to duplicate logic into three scripts. Consider this tree
Root container
Release Samples
Legato Samples
Sustain Samples
You would then add one script with release trigger functionality on the first child (this is one line of code), legato logic on the second (again 2 - 5 lines of code to get basic legato transitions working) and a script on the sustain sample that does whatever you like (can't think of a useful script in this simple context
But now you want to change the velocity curve for the instrument. This should affect all samples so you add one ScriptProcessor on the root container with a script that allows this functionality.
@167ixo55:
For example, in one hypothetical case, slide samples could be used as part of a complex legato script in a note-on event, or triggered on release (sliding down from the released note).
This can be achieved by adding some code in the onNoteOff callback of the legato script. Something like that should be enough:
function onNoteOff()
{
if(legatoReleaseWanted()) // whatever condition you need
{
Synth.enableRoundRobin(Message.getNoteNumber()); // set the group to the note number (in legato samplers I advice using the groups as start note numbers)
Synth.playNote(Message.getNoteNumber() - 12, whateverVelocity); // play the octave down slide
}
}
Another way would be to reuse the same samples in another sampler called "Release Trigger Downslide" (samples will not be loaded twice if they are referenced in two "zones" or samplers). This approach would be better if you want eg. different envelope times for the two types.
I also encourage you for more examples and use cases - I can understand this different data structure concept needs a different approach in the instrument design but I am confident this is the way to go.