1. IMPORTANT:
    We launched a new online community and this space is now closed. This community will be available as a read-only resources until further notice.
    JOIN US HERE

Solved Revisiting LFO tempo sync

Discussion in 'Scripting Workshop' started by Ferdinand de Bretancourt, Jan 8, 2017.

  1. Ferdinand de Bretancourt

    Ferdinand de Bretancourt NI Product Owner

    Messages:
    74
    I have made an LFO section with custom knobs, and want a separate dropdown menu with time signatures (8th, 16th, 32 etc ...).
    I can't find a way to do it. I know about $DURATION but have no clue if it can be tied in with the LFO tempo sync.
    Did find a 2011 comment from EvilDragon that it was extremely hard to script, but maybe in 5 or 6 years, someone found an easier way.

    Of course I could make separate LFO's with different settings, and call upon them from a dropdown menu, but I have reached the maximum amount of destinations that Kontakt allows for. So that option is out the door.

    Preparing for the bad news .... :(
     
  2. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    With Kontakt 5.5 temposyncing stuff in Kontakt was overhauled. See KSP reference, there are new engine parameters and time constants you can use to temposync much more easily.
     
  3. Ferdinand de Bretancourt

    Ferdinand de Bretancourt NI Product Owner

    Messages:
    74
    I just came home and saw your comment. I didn't even realize I was using the 2011 KSP reference all this time. Never thought about getting a new version lol. I got the 5.5 KSP reference now and immediately I saw the $ENGINE_PAR_INTMOD_FREQUENCY_UNIT.
    I think that is what I am looking for. I will puzzle away and see how it works.

    Thanks EvilDragon! :thumbsup:
     
  4. Ferdinand de Bretancourt

    Ferdinand de Bretancourt NI Product Owner

    Messages:
    74
    supplement:

    It works! The only thing I am getting are errors for certain values.
    I declare a ui_slider with values 0-16 to control the sync values, but values 1,2,3,4,11,14 are generating errors, and therefore not reaching all tempo values (max knob value stops at sixteenth's).

    SCRIPT WARNING: set_engine(): note value is not accepted

    Consequently I have created a workaround, and declared a ui_slider with values 0-21, which does reach all tempo values (default to 256). Must be some Kontakt thing. Just wanted to throw this into the group.
     
  5. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    Max knob value in the new tempo sync mode is 12 - don't mix up the unit variables with actual knob positions (which are still 0-1000000 range). By changing the knob value you can get dotted values.

    I hope you're using arrays to pick out the time constants for the unit parameter. I do this with two arrays: one for unit, one for knob value, and this way I spread the whole range from 1/256 to 12/1, including dotted notes.
     
  6. Ferdinand de Bretancourt

    Ferdinand de Bretancourt NI Product Owner

    Messages:
    74
    I actually do not use arrays. I am just barely getting by with my very limited programming skills. What others do in an hour, will take me 2 weeks :(. Like a Cave man trying to paint a Rembrandt. He will get some of it right, but most will be way off.
    I appreciate your logic, but I can't translate it into a working plan. I did look in the KSP ref for some pointers, but I perhaps understand 20% of it. Not to be lazy, but the knob works, albeit very very sloppy. Wish I could do better.
    Hoping to get more into the ksp basics as I go along. :)
     
  7. soundtrax

    soundtrax NI Product Owner

    Messages:
    301
    EvilDragon - would be cool if you could post a little example using arrays.

    Here's a rather simple script example without using arrays - with a tempo synced LFO range from slow to fast (1Bar - 1/64th)
    I defined one knob with 12 knob positions, but of course you could set up more.
    the first set_engine_par sets the unit, the 2nd sets the value. The name of the LFO must be "LFO_MULTI".
    Code:
    on init
        set_script_title("LFO Tempo Sync")
        set_ui_height_px(50)
        message("")
        make_perfview
    
    { Knob LFO Rate }
    
    declare ui_knob $LFORate(0, 11, 1)
    
    end on
    
    { PITCH LFO Rate - name of LFO must be "LFO_MULTI"! }
    
    on ui_control ($LFORate)
    
    if ($LFORate = 0)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_QUARTER,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_QUARTER_TRIPLET,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 2)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_8TH,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 3)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_8TH_TRIPLET,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 4)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_16TH,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 5)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_16TH_TRIPLET,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 6)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_32ND,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 7)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_32ND_TRIPLET,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 8)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_64TH,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 9)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_64TH_TRIPLET,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 10)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_256TH,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,400000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 11)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_256TH,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,700000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    if ($LFORate = 12)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY_UNIT,$NI_SYNC_UNIT_256TH,0,find_mod(0,"LFO_MULTI"),-1)
    set_engine_par($ENGINE_PAR_INTMOD_FREQUENCY,900000,0,find_mod(0,"LFO_MULTI"),-1)
    end if
    
    end on
    
     
  8. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    It's pretty simple, you just need one array for all the units, and one array for the knob values. Do be aware that you need a different pair of arrays depending on parameter: delay time has its own, chorus/phaser/flanger have their own (the same for all three), LFO/step mod frequency has its own, and envelopes are the same as LFO but in reverse.

    Code:
    on init
        declare const NUM_FX_SYNC_TIMES := 20
        declare const NUM_MOD_SYNC_TIMES := 34
    
        declare dly_sync_unit[NUM_FX_SYNC_TIMES] := (NI_SYNC_UNIT_64TH_TRIPLET,NI_SYNC_UNIT_64TH,NI_SYNC_UNIT_32ND_TRIPLET,NI_SYNC_UNIT_256TH,NI_SYNC_UNIT_32ND,NI_SYNC_UNIT_16TH_TRIPLET,NI_SYNC_UNIT_64TH,NI_SYNC_UNIT_16TH,NI_SYNC_UNIT_8TH_TRIPLET,NI_SYNC_UNIT_32ND,NI_SYNC_UNIT_8TH,NI_SYNC_UNIT_QUARTER_TRIPLET,NI_SYNC_UNIT_16TH,NI_SYNC_UNIT_QUARTER,NI_SYNC_UNIT_HALF_TRIPLET,NI_SYNC_UNIT_8TH,NI_SYNC_UNIT_HALF,NI_SYNC_UNIT_WHOLE_TRIPLET,NI_SYNC_UNIT_QUARTER,NI_SYNC_UNIT_WHOLE)
        declare dly_sync_value[NUM_FX_SYNC_TIMES] := (0,0,0,454545,0,0,181818,0,0,181818,0,0,181818,0,0,181818,0,0,181818,0)
        declare cfp_sync_unit[NUM_FX_SYNC_TIMES] := (NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_QUARTER,NI_SYNC_UNIT_WHOLE_TRIPLET,NI_SYNC_UNIT_HALF,NI_SYNC_UNIT_8TH,NI_SYNC_UNIT_HALF_TRIPLET,NI_SYNC_UNIT_QUARTER,NI_SYNC_UNIT_16TH,NI_SYNC_UNIT_QUARTER_TRIPLET,NI_SYNC_UNIT_8TH,NI_SYNC_UNIT_32ND,NI_SYNC_UNIT_8TH_TRIPLET,NI_SYNC_UNIT_16TH,NI_SYNC_UNIT_64TH,NI_SYNC_UNIT_16TH_TRIPLET,NI_SYNC_UNIT_32ND,NI_SYNC_UNIT_256TH,NI_SYNC_UNIT_32ND_TRIPLET,NI_SYNC_UNIT_64TH,NI_SYNC_UNIT_64TH_TRIPLET)
        declare cfp_sync_value[NUM_FX_SYNC_TIMES] := (1000000,545454,1000000,1000000,545454,1000000,1000000,818181,1000000,1000000,818181,1000000,1000000,818181,1000000,1000000,818181,1000000,818181,1000000)
        declare mod_sync_units[NUM_MOD_SYNC_TIMES] := (NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_WHOLE,NI_SYNC_UNIT_QUARTER,NI_SYNC_UNIT_WHOLE_TRIPLET,NI_SYNC_UNIT_HALF,NI_SYNC_UNIT_8TH,NI_SYNC_UNIT_HALF_TRIPLET,NI_SYNC_UNIT_QUARTER,NI_SYNC_UNIT_16TH,NI_SYNC_UNIT_QUARTER_TRIPLET,NI_SYNC_UNIT_8TH,NI_SYNC_UNIT_32ND,NI_SYNC_UNIT_8TH_TRIPLET,NI_SYNC_UNIT_16TH,NI_SYNC_UNIT_64TH,NI_SYNC_UNIT_16TH_TRIPLET,NI_SYNC_UNIT_32ND,NI_SYNC_UNIT_256TH,NI_SYNC_UNIT_32ND_TRIPLET,NI_SYNC_UNIT_64TH,NI_SYNC_UNIT_256TH,NI_SYNC_UNIT_64TH,NI_SYNC_UNIT_256TH,NI_SYNC_UNIT_256TH)
        declare mod_sync_value[NUM_MOD_SYNC_TIMES] := (0,90909,181818,272727,363636,454545,545454,636363,727272,818181,909090,999999,818181,999999,999999,818181,999999,999999,818181,999999,999999,818181,999999,999999,818181,999999,999999,545454,999999,999999,818181,999999,909090,999999)
    end on
    
    That's all you need. No need for a huge chain of "if" clauses :)
     
    Last edited: Jun 8, 2018
  9. soundtrax

    soundtrax NI Product Owner

    Messages:
    301
    thanks very much :)
    so you'd need two knobs - one for the units, the other one for the dividers, right?
     
  10. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    No, one knob reads from both arrays at the same time. First the unit, then the value.

    With a bit of math, you can make the same knob to work in unsynced and synced mode - the knob has to be 0-1000000, and then you'd need to scale it so that it fits the range of the array you need (in above case, 0 to 19 or 0 to 33).
     
  11. soundtrax

    soundtrax NI Product Owner

    Messages:
    301
    cool - will check it out!
     
  12. soundtrax

    soundtrax NI Product Owner

    Messages:
    301
    EvilDragon - I am still trying to understand how to properly script arrays…would be great if you could maybe help.
    If I load your quick example into kontakt, an error message appears: "line 2: variable missing".
    I am not sure which parts of your code are supposed to be variables, and which need the array (%) sign before their names...
    (and in the KSP manual the declaration of arrays (p. 20) looks quite different to your code) so I don't really know what I'd need to change to make it work. Thanks!!
     
  13. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    My code was intended for SublimeKSP editor...

    Anyways, all arrays need a %, naturally, only the first two variables (which are constants) need $.
     
  14. soundtrax

    soundtrax NI Product Owner

    Messages:
    301
    okay, I see - thanks! That's what I actually tried, but then I forget to add "$" to all the sync time units as well, so the error messages never stopped.

    (I don't use the sublimeKSP editor, only TextWrangler, but maybe I should check it out.)
     
  15. Lindon

    Lindon NI Product Owner

    Messages:
    322
    if you want serious help in either of the KSP forums you will find we nearly ALL use Sublime text with Nils' KSP plug-in.
     
  16. soundtrax

    soundtrax NI Product Owner

    Messages:
    301
    btw. there's an underscore missing in Mario's script. It must be (in non-Sublime code):
    Code:
    declare const $NUM_MOD_SYNC_TIMES := 34
    instead of
    Code:
    declare const $NUM_MOD SYNC_TIMES := 34
    (I also had problems when I tried to compile the code: SublimeText wouldn't automatically add the necessary "const" for the declaration of the variables which produced an error message in Kontakt. But I'm not sure if I had all Sublime settings right (?) - still struggling with the SublimeText editor...)
     
  17. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    Ah, I see it now. Fixed the original post, thanks. :)
     
    • Like Like x 1
  18. medusa

    medusa NI Product Owner

    Messages:
    239
    Mario, with this array, how do you set the delay time to say, for example "Three eighth triplets"? I can only seem to get it to set a single unit of each sync value.
     
  19. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    Wouldn't 3x 8th triplets be a quarter note? :)

    In any case, the answer would be in dly_sync_value[] array - it contains $ENGINE_PAR_DL_TIME values that adjust the delay timebase multiplier (1.0 to 12.0). If you want custom values there, you'd need to modify that array (and of course the dly_sync_unit[] array along with it, they gotta match).
     
    Last edited: May 25, 2018
  20. medusa

    medusa NI Product Owner

    Messages:
    239
    Right, but it would then have to be fixed in advance? I think I prefer keeping the sync value and the number of units seperate... more flexible.