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

How to script tremolo or vibrato

Discussion in 'Scripting Workshop' started by Oneiroi, Sep 18, 2020.

  1. Oneiroi

    Oneiroi NI Product Owner

    Messages:
    30
    I know about dynamiTec's ultra vib and ultra tremolo scripts, but I'm creating a performance script with all of my default modulations and CC mappings all together, so I can simply add that to all of my instruments and don't need to go through the whole process of creating modulations, etc...and these scripts are just way too complex and dense to integrate inside mine. I also like having more script slots available. And...it's also fun just learning how to do stuff.

    So, I'm wondering if any of you could help me out in creating a tremolo/vibrato script which I will then incorporate into my super script. I just want control over the amount and speed, no need for fade-ins and randomness. I'm still quite new with scripting in general, so this is still a little over my head, but I think I'll be able to handle it quite quickly. I just need a bit of help with the maths to be honest. I'm guessing we will need to use sin(x) function with a while loop?

    Thanks!
     
  2. corbo-billy

    corbo-billy NI Product Owner

    Messages:
    652
    You can try the factory script .


    Trigger.jpg
     
  3. Oneiroi

    Oneiroi NI Product Owner

    Messages:
    30
    By tremolo, I meant a sine LFO that modulates the volume, just like you normally hear on vibraphones.
     
  4. corbo-billy

    corbo-billy NI Product Owner

    Messages:
    652
    Interesting topic on modulations _
     
  5. Oneiroi

    Oneiroi NI Product Owner

    Messages:
    30
    Was there supposed to be a link there?
     
  6. corbo-billy

    corbo-billy NI Product Owner

    Messages:
    652
  7. Oneiroi

    Oneiroi NI Product Owner

    Messages:
    30
    Ah, yes I'm well aware of how to control modulation via scripting, but I'd really love to not have to create any modulation manually, just like Big Bob or dynamiTec scripts (I know I'm being picky, but I'd love to have a script with all the effects and performance tools that I can just load and everything is already perfectly setup...makes a big difference with huge libraries). So unless there is a way to create the modulations via scripting (which, according to the KSP manual, there isn't) I'd have to use the change_vol or change_tune functions inside a while loop. I was just curious if anyone knew a bit of the maths necessary to create a sine LFO via scripting...
     
  8. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
  9. Oneiroi

    Oneiroi NI Product Owner

    Messages:
    30
    Nice, thank you! I'll try this later, but if I understand correctly, the number of points in this sine table generator multiplied by the wait time will determine the resolution of my lfo? So I'd need to gauge the number of points to an amount which would be smooth enough and not so CPU consuming within the LFO speed range I'm planning to use?

    In other words, are higher-speed LFOs more CPU demanding, because they require to lookup more array values per second? And lower-speed LFOs run the risk of being "grainy" if the array size is too small?
     
  10. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    In practice you can also just use the sin() function that has been there since K5.6.
     
  11. Oneiroi

    Oneiroi NI Product Owner

    Messages:
    30
    Thank you. The sine function worked well for monophonic tremolo (using the listener callback) but how do I use it for polyphonic modulation if real variables can't be polyphonic (the sine function argument needs to be a real number)? Here's what I came up with so far.

    Code:
    on init
        declare ui_table %lfo_graph[2] (2,16,-40000)
    
        declare ui_knob $Trem_Amount (0,100,1)
        set_text($Trem_Amount, "Amount")
        set_knob_unit($Trem_Amount, $KNOB_UNIT_PERCENT)
        make_persistent($Trem_Amount)
    
        declare ui_knob $Trem_Speed (0,100,1)
        set_text($Trem_Speed, "Speed")
        set_knob_unit($Trem_Speed, $KNOB_UNIT_PERCENT)
        make_persistent($Trem_Speed)
    
        declare ui_button $Trem_Mode
        set_text($Trem_Mode, "Poly")
        make_persistent($Trem_Mode)
    
        declare ~trem_amount
        ~trem_amount := int_to_real($Trem_Amount) * 200.0
    
        declare ~trem_speed
        ~trem_speed := int_to_real($Trem_Speed) / 3000.0 + 0.009
    
        declare $lfos_res := 1000
        declare ~count := 0.0
        declare ~trem_real
        declare $trem_int
        set_listener($NI_SIGNAL_TIMER_MS, $lfos_res)
    end on
    
    on note
        set_event_mark($ALL_EVENTS, 1)
        if ($Trem_Mode = 1 and $Trem_Amount > 0)
            ~count := 0.0
            while ($NOTE_HELD = 1)
                ~trem_real := sin(~count)
                $trem_int := real_to_int(~trem_real * ~trem_amount - ~trem_amount)
                %lfo_graph[1] := $trem_int
                wait ($lfos_res)
                ~count := ~count + ~trem_speed
                change_vol(by_marks(1), $trem_int, 0)
            end while
        end if
    end on
    
    on listener
        if ($NI_SIGNAL_TYPE = $NI_SIGNAL_TIMER_MS and $Trem_Mode = 0 and $Trem_Amount > 0)
            ~trem_real := sin(~count)
            $trem_int := real_to_int(~trem_real * ~trem_amount - ~trem_amount)
            %lfo_graph[1] := $trem_int
            wait ($lfos_res)
            ~count := ~count + ~trem_speed
            change_vol(by_marks(1), $trem_int, 0)
        end if
    end on
    
    
    on ui_control ($Trem_Amount)
        ~trem_amount := int_to_real($Trem_Amount) * 200.0
    end on
    
    on ui_control ($Trem_Speed)
        ~trem_speed := int_to_real($Trem_Speed) / 2000.0 + 0.009
    end on
     
  12. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    Probably not a fun solution, but you can always multiply the result of sine (bound -1 ... 1) by 1000000, store to polyvar, then use that.
     
  13. Reid115

    Reid115 NI Product Owner

    Messages:
    40
    For custom polyphonic modulators, is there any significant difference in efficiency (or any other advantages/disadvantages) between 1) doing a wait() loop in the NCB vs. 2) getting the events in the LCB and applying the modulation there? Because the latter is possible now with the "from script" modulator. This is assuming the NCB wait time and the listener rate are the same in both scenarios. If there's no discernable difference, I would think the NCB method would be better because any voice-specific variables that may be needed for mod calculation are right there in the same scope.
     
  14. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    If you need a global tremolo rather than per voice one, I would still use the listener callback. It's simply more logical that way.
     
  15. Reid115

    Reid115 NI Product Owner

    Messages:
    40
    I'm asking about polyphonic (per-voice).