KSP is hard

cpaf

Member
For someone just getting wet into ksp its awesome to hear your opinions all - didnt know about HISE before reading this thread - also learned a lot about Kontakts functionality. I am biased towards Kontakt at the moment (as a beginner) as it is the most used and recognised. HISE sounds like Bitwig but I need/want Cubase to compose which to me is like Kontakt.

But I do hope the Kontakt team is looking forward and think about moving towards a newer programming foundation than pascal.
 

Fredeke

Senior Member
Ay. A painful realization just dawned on me.

I hate to bother with variable types. I like PHP (and, to most extent, javascript) because it takes care of them for me - even though I need to keep aware of what it's doing in that respect. I loved GfA back on the Atari ST because I could choose to go low level and be rigorous, or stay high level and be sloppy - which I did, most of the time.

Anyway, one reason I find KSP tedious is because of how strict it is when it comes to types, and it pains me how simple formulaes become unreadable when you nest int_to_real's into real_to_int's... But then, I do need it to be as efficiently real time as possible, so even with a better language, I suppose I should still manage variable types myself for better code efficiency.

So there's no way around this annoyance. And that's a cruel truth.
(Life does what a vacuum does best.)
 

szcz

Member
Once I got used to it, I rather like KSP, I find it quite easy, since real math arrived you can do a lot with it. Strict types are good, you know what are you dealing with and you're not wasting resources. Somehow I find KSP much simpler and comfortable than SublimeKSP, I really hate what I have to deal with it, it's like adding layers of nonsense to something that is already convoluted enough. I think that people with previous programming background find KSP odd, as it has a slightly different mindset, then Sublime acts as prostetic to make it look more familiar. Actually Kontakt itself is harder than KSP, it's just such a mess here and there, like the timing controllers for Replika and Phasis that have different polarity for no apparent reason, many small quirks like that.
 

Fredeke

Senior Member
Somehow I find KSP much simpler and comfortable than SublimeKSP, I really hate what I have to deal with it, it's like adding layers of nonsense to something that is already convoluted enough.
I understand SublimeKSP could be too bothersome to learn (especially with its fragmented doc), especially if your projects are simple enough to dispense with it. But for what I've been tackling, I could hardly do without the comforts of its features making KSP at least half resemble a modern language. It has been a lifesaver in some situations.

Of course, I worry that the preprocessed script becomes a humongous mess in regular KSP when I use some of the more sophisticated features, which would defeat the speed of execution that is the original lack of feature's only (and yet debatable) justification.

Is SublimeKSP more convoluted? Yes, obviously. That's its whole point. But I would rather say it's regular KSP that is not convoluted enough. Which requires you to write sometimes excessively extensive scripts - maybe that's what you meant.

Indeed you could call Kontakt's engine convoluted (or at least incoherent in places, as you seem to do), and so KSP's integration into it. But KSP itself is too basic as well as too straightforward if anything.

Note that SublimeKSP is the only aid I've used so far. I hear there are more. I welcome any suggestion.
 
Last edited:

szcz

Member
I understand SublimeKSP could be too bothersome to learn (especially with its fragmented doc), especially if your projects are simple enough to dispense with it.
I don't think it's complexity that matters here, I believe I have been dealing with fairly complex stuff (as far as Kontakt goes), maybe not, I don't know what are you dealing with. Anyway, what I meant, it's mainly a frame of mind problem. What I see, is that people who already program in some language seem to hate KSP when they are exposed to it. I had little programing experience prior to KSP and that was in 8 bit some long time ago, which is possibly why I have no discomfort here.
 

Dewdman42

Senior Member
if and when I start doing some KSP stuff, I personally will first learn NI's KSP language directly. Later I will see what Nil's approach might do for me. Especially since Nil's approach is basically a pre-processor that produces KSP, I feel its important to understand even the generated KSP. There are always pros and cons to using a higher level language that generates a lower level language. It can make some things easier and some things more difficult. I say that in complete ignorance about both KSP and Nil's stuff, but extensive experience as a software developer that has had to deal with various kinds of preprocessors over the years. They can be a blessing and/or a curse. If KSP is unnecessarily terse, then I'm sure I will run to Nil's stuff pretty quickly or make my own way of dealing with specific annoyances.

Having to specify the type for variables doesn't bother me in the least, in fact I may prefer that. But if there are some common tasks such as building up arrays of interface controls or something like that I could totally see why it would be beneficial. I am mostly only interested in simple and efficient midi processing myself...so possibly I may prefer to use the lowest language possible...ie...KSP. but we shall see.

Incidentally I have a question for you KSP gurus before I spend time trying to figure out if its even possible... There is currently a "bug" in Kontakt5 ( I haven't tested K6 for this), which has to do with the way CC automation is handled. Specifically, it seems that in any process block of time, Kontakt seems to process first the CC automation events, followed by any note events in that process block. That is a problem if you have a need to have a specific ordering of CC-note-CC-note-CC-note all on the exact same point in time, like a chord, with each voice of the chord having a different CC value applied to it. This comes up with articulation handling in some Kontakt libraries for chords with poly-articulations and using CC as the switch for each note. I am wanting to see if there is some way with a KSP multi-script to work around that problem in kontakt where it seems to, for any given point in time, first process all CC's followed by al notes (in that case the last CC wins control over all notes of the chord). But I don't know how and where KSP sits in the midi signal flow in kontakt or whether it would somehow be possible to script around that annoyance in kontakt. Anyone have an idea about that? Particularly this came up for me when I was using the cc automation section in kontakt to receive CC's and change parameters in the instrument. That all happens before any notes are processed, not necessarily in the order the cc-note-cc-note's were sent from the host to the plugin.
 

EvilDragon

KSP Wizard
If KSP is unnecessarily terse
It quite is :)

Would you rather write:

Code:
define NUM_SLIDERS := 10
declare ui_slider Slider[NUM_SLIDERS] (0, 1000000)
or:

Code:
declare ui_slider $Slider0 (0, 1000000)
declare ui_slider $Slider1 (0, 1000000)
declare ui_slider $Slider2 (0, 1000000)
declare ui_slider $Slider3 (0, 1000000)
declare ui_slider $Slider4 (0, 1000000)
declare ui_slider $Slider5 (0, 1000000)
declare ui_slider $Slider6 (0, 1000000)
declare ui_slider $Slider7 (0, 1000000)
declare ui_slider $Slider8 (0, 1000000)
declare ui_slider $Slider9 (0, 1000000)

;)
 
Last edited:

P.N.

Senior Member
Especially since Nil's approach is basically a pre-processor that produces KSP, I feel its important to understand even the generated KSP. There are always pros and cons to using a higher level language that generates a lower level language. It can make some things easier and some things more difficult. I say that in complete ignorance about both KSP and Nil's stuff, but extensive experience as a software developer that has had to deal with various kinds of preprocessors over the years. They can be a blessing and/or a curse.
I'm not a software developer, but i agree. Not getting the underlying code can be frustrating and detrimental.
I always try to understand the code on its lowest level. That's where i feel i can produce better logical decisions, at least for more complex custom tasks.

About the synthax... well, it is what it is. It's probably the worst thing about going full vanilla.

I wouldn't say "Never go full vanilla", but i can see its shortcomings too, sure.
 

Dewdman42

Senior Member
On script level events appear in host programmed order, so if you script automation it may solve the problem.
That is good to know, So KSP multi-script could access the automatable parameters of a commercial sample instrument, same as Kontakt's CC automation does?

I have to do some experiments again to see if that will still preserve the ordering of the instrument itself processing cc-c-note-cc-note, in that preserved queue order when they are all on the same beat/sample position.
 

Dewdman42

Senior Member
It quite is :)

Would you rather write:

Code:
define NUM_SLIDERS := 10
declare ui_slider Slider[NUM_SLIDERS] (0, 1000000)
or:

Code:
declare ui_slider $Slider0 (0, 1000000)
declare ui_slider $Slider1 (0, 1000000)
declare ui_slider $Slider2 (0, 1000000)
declare ui_slider $Slider3 (0, 1000000)
declare ui_slider $Slider4 (0, 1000000)
declare ui_slider $Slider5 (0, 1000000)
declare ui_slider $Slider6 (0, 1000000)
declare ui_slider $Slider7 (0, 1000000)
declare ui_slider $Slider8 (0, 1000000)
declare ui_slider $Slider9 (0, 1000000)

;)
In answer to that question, "it depends". Yes on the surface, it may be easier to use the one liner, they all have 100000 param for some purpose. if they are all slightly different, then I'd rather use the low level stuff.

Question for you. If you use the declare macro above...can you later in the script refer to $Slider1 directly even though you never actually coded a declare for that control yourself?
 

szcz

Member
So KSP multi-script could access the automatable parameters of a commercial sample instrument, same as Kontakt's CC automation does?
Not really, multiscript can only process MIDI stream. So you would have change/add code at instrument level to make CC interact with given parameter. If it's commercial lib, hard luck as the script is most likely locked.
You can load factory MIDI monitor script into empty instrument and see that the event queue is preserved. It is for me, feeding from Sonar to Kontakt 5.

What are you trying to achieve? Microtuning by chance?
 

P.N.

Senior Member
Anyway, one reason I find KSP tedious is because of how strict it is when it comes to types, and it pains me how simple formulaes become unreadable when you nest int_to_real's into real_to_int's...
Are you saying that something like this is unreadable? (circle)

Code:
              {x}%records[%rec_str[0] + $count + %rec_offset[$count2]] := real_to_int((0.50 + (int_to_real($radius) / 1000.0) * sin(~NI_MATH_PI * int_to_real($count) / int_to_real($pb_bars * $BAR_LENGTH) * int_to_real($pb_bars) * 2.0 - ~NI_MATH_PI / 2.0)) * 1000.0)
              {y}%records[%rec_str[0] + $REC_MAX + $count + %rec_offset[$count2]] := abs(real_to_int((0.50 + (int_to_real($radius) / 1000.0) * cos(~NI_MATH_PI * int_to_real($count) / int_to_real($pb_bars * $BAR_LENGTH) * int_to_real($pb_bars) * 2.0 - ~NI_MATH_PI / 2.0)) * 1000.0))
Be reasonable... :laugh:
 

Dewdman42

Senior Member
Not really, multiscript can only process MIDI stream. So you would have change/add code at instrument level to make CC interact with given parameter. If it's commercial lib, hard luck as the script is most likely locked.
You can load factory MIDI monitor script into empty instrument and see that the event queue is preserved. It is for me, feeding from Sonar to Kontakt 5.

What are you trying to achieve? Microtuning by chance?
I was afraid of that. Yes it came up particularly for one commercial lib I sometimes use (Kirk Hunter) and its locked of course. There are a couple of functions on there that he does not provide a good keyswitch for, he provides a "toggle" which is a bad idea because an articulation system has no way of knowing whether its on or off currently. But of course you can easily use cc automation in kontakt to turn that particular control on or off directly (rather then toggling with the keyswitch he provided). I wrote some LogicPro scripts to send that CC per articulationID when needed, but what I found in my testing was that if you have a chord with different articulations on each note of the chord (yes, rare situation, but still), then the CC's from automation all get processed by the instrument before any of the notes. So the last CC sent from host...goes through automation...changes that control to whatever is it, then finally all the notes of the chord are processed by the instrument...and that is the problem.

I have heard other people complaining about hard to solve CC switch issues in some Kontakt instruments, and I suspect its also related to this, but I don't know for sure whether this is a problem from using CC automation in kontakt as i was trying to do, or if kontakt is actually processing all CC's before notes. I suspect it has to do with Kontakt processing all the cc automation for a given beatpos before the notes. So the instrument has no control over it, I can't change the instrument anyway...and it sounds like a multi-script may not be able to work around it either.
 

szcz

Member
LogicPro scripts to send that CC per articulationID when needed...
I see, I haven't tested how it works with automation... However I think it could be handled at multiscript level. Basically I guess what would need to be done, is to add microdelays if events arrive at the same song position, 300 microsecond delay is not audible, but would set order within the instrument processing. Or perhaps you can do that in Logic script? I would load MIDI monitor into Kontakt first and check if the events really arrive in order, maybe the problem is at host level...
 

Fredeke

Senior Member
I don't think it's complexity that matters here, I believe I have been dealing with fairly complex stuff (as far as Kontakt goes), maybe not, I don't know what are you dealing with. Anyway, what I meant, it's mainly a frame of mind problem. What I see, is that people who already program in some language seem to hate KSP when they are exposed to it. I had little programing experience prior to KSP and that was in 8 bit some long time ago, which is possibly why I have no discomfort here.
On one hand, I can respect that, as it's been my own stance more than once.
On the other, I can't help thinking you're missing out.

Especially since Nil's approach is basically a pre-processor that produces KSP, I feel its important to understand even the generated KSP.
That's definitely right.

Just tonight, I had to go check what the preprocessor was spurting out in order to understand why I was using it wrong.

It's a good idea to begin with regular KSP. But you'll want some meat with your potatoes soon enough.

Question for you. If you use the declare macro above...can you later in the script refer to $Slider1 directly even though you never actually coded a declare for that control yourself?
Yes of course.

I think you could write $Slider[1] (as in first element of an array) and the preprocessor would translate that to $Slider1, or you can write $Slider1 directly. (A senior member will surely correct me if I'm wrong)

Btw, EvilDragon's example is very basic. There are shortcuts in SumblimeKSP that would fill the height of your screen several times over in KSP, and not because of mere repetitions. (Well, ok, partly because of them. But not just.)
 
Last edited:

Dewdman42

Senior Member
I have thought of doing some stuff like that where I detect that poly-articulation situation and add some delay, which from Logic Pro the least amount of delay possible from Scripter is 1/960th of a beat. Probably small enough to not detect as you say. But I'd actually rather have a multi-script do it in kontakt so that my Articulation Scripts don't have to have that in them complicating them all... one simple kontakt-fixer multi-script would be easier. Sounds like maybe I might be able to get a smaller delay with multi-script also if you're able to schedule things there based on sample position rather then beat pos.

and yea I did already check with the monitor. Host was sending exactly as intended.
 

Dewdman42

Senior Member
I guess another question would be this...KSP multi-script...is that before CC automation also? And presumably kontakt processes cc automation once per process block...which is generally the size in time of the audio sample buffer. so all events within that window would be processed together..first the CC automation, then the notes. So basically any kind of script would need to delay each note in the poly-articulation chord by enough of an amount to go to separate process blocks each. I think? That most likely means something more like 1ms apart.
 

EvilDragon

KSP Wizard
Question for you. If you use the declare macro above...can you later in the script refer to $Slider1 directly even though you never actually coded a declare for that control yourself?
Yes, the code above also creates an array containing UI ID arrays for direct access to the control, by using <name-of-control>[x] array. But also yes, you can use the direct name of any of the generated sliders directly. So you can:

Code:
define NUM_SLIDERS := 10
declare ui_slider Slider[NUM_SLIDERS] (0, 1000000)

Slider6 := 100


KSP multi-script...is that before CC automation also?
Multiscript intercepts all incoming MIDI, AFAIK.


And presumably kontakt processes cc automation once per process block...
Kontakt processes things internally in 32 samples buffers.




I think you could write $Slider[1] (as in first element of an array)
Second element of the array ;) And you'd write %Slider[1], of course. Or just not use %, because meh. :)

And it actually doesn't translate to $Slider1, it translates to get_ui_id($Slider1). :)
 
Last edited:

szcz

Member
I guess another question would be this...KSP multi-script...is that before CC automation also?
Easy to check. Such script ain't complicated, try this...

Code:
on init
    
    set_script_title("force schedule")
    
    {
    detect events that occur within given frame (value in milliceconds - 1/1000 s),
    delay all events that occur within the timeframe by defined delay (value in microseconds = 1/1000000),
    second event receives double delay, third received tripple delay and so on...
    }
    
    declare ui_value_edit $delay(100,5000,1)
    declare ui_value_edit $frame(1,200,1)
    declare ui_button $on
    $delay := 500
    
    declare $x
    declare $event_counter
    declare $time_checkpoint
    
    make_persistent($delay)
    make_persistent($frame)
    make_persistent($on)
    
end on

on midi_in
    if($on =1)
        if($MIDI_COMMAND = $MIDI_COMMAND_NOTE_OFF or $MIDI_COMMAND = $MIDI_COMMAND_NOTE_ON or $MIDI_COMMAND = $MIDI_COMMAND_CC) {only process notes and CC}
            
            $x := $ENGINE_UPTIME - $time_checkpoint {how much time passed from last event?}
                
            if($x <= $frame) {not enough, delay event}
                inc($event_counter)
                ignore_midi
                wait($delay * $event_counter)
                set_midi($MIDI_CHANNEL,$MIDI_COMMAND,$MIDI_BYTE_1,$MIDI_BYTE_2)
            else
                $time_checkpoint := $ENGINE_UPTIME
                $event_counter := 0
            end if
            
        end if
    end if
end on
Just note that frame is in milliseconds and delay in microseconds (that's very short, so 5000 is 5 ms delay, practically inaudible). As I checked in Sonar, frame=1 catches all four notes aligned at certain position in my host.
Note that it could potentially make stuck notes, if you had a super-short notes defined in your host (like 1ms duration) your 'note on' could be delayed so it would go after 'note off'. Not very likely in practice, but for the record...