Populating a table with a sine wave

Discussion in 'Scripting Workshop' started by Lovechld2000, Apr 6, 2019.

  1. Lovechld2000

    Lovechld2000 NI Product Owner

    Messages:
    234
    I'm pretty sure the code is close because I'm seeing sine like shapes inputing data, but my math or how it relates to the function is letting me down here. I wanted it to give me one cycle of a sine wave starting at the first element with a period of the total 128. Thinking about it maybe the amp should be 500000.0 and it should start at 500000.0 but not sure how to make it do that

    Code:
    function create_sine
        $i := 0
        while ($i < 128)
            ~scalc := int_to_real($i)
            ~stotal := 1000000.0 * sin(~scalc/(128.0 * ~scalc)) {100000.0 is the amplitude and 128.0 is the period}
            %tbl_poptest[$i] := real_to_int(~stotal)
            inc($i)
        end while
    end function
    Full demo here using sublime

    Code:
    on init    
        make_perfview
        set_ui_height_px(200)
        declare $i
        declare ~scalc
        declare ~stotal
        ui_tabler(poptest,128,50,50,300,75,1000000)
    end on
    
    
    on note
        call create_sine
    end on
    
    function create_sine
        $i := 0
        while ($i < 128)
            ~scalc := int_to_real($i)
            ~stotal := 1000000.0 * sin(~scalc/(128.0 * ~scalc)) {100000.0 is the amplitude and 128.0 is the period}
            %tbl_poptest[$i] := real_to_int(~stotal)
            inc($i)
        end while
    end function
    
    
    
    macro ui_tabler(#name#,elements,x,y,width,height,range)
        declare ui_table %tbl_#name#[elements](1,1,range)
        move_control_px(%tbl_#name#, x, y)
        %tbl_#name# -> WIDTH := width
        %tbl_#name# -> HEIGHT := height
        make_persistent (%tbl_#name#)
    end macro
     
  2. EvilDragon

    EvilDragon Moderator Moderator

    Messages:
    14,609
    When dealing with trigonometric functions, you should probably use radians, which means that tau, otherwise known as 2*π, is your best friend. Then you use the generic formula to go along any point of the sine:

    Code:
    sin(2.0 * ~NI_MATH_PI * ~freq * ~time)
    With ~freq being frequency in Hz (in this case we don't use it so it's 1), and ~time being in milliseconds (so 0 to 1000 because our freq is 1 Hz).

    Then you multiply the output of that with 1000000 and convert to integer.
     
  3. Lovechld2000

    Lovechld2000 NI Product Owner

    Messages:
    234
    ah yes I've seen the radian expression before. Can you help me with the syntax in this instance please?
    I was expecting this to work , assuming time is a set of 128 table elements. I left 1.0 in there in case I want 2.0 as well

    Code:
    function create_sine
        $i := 0
        while ($i < 128)
            %tbl_poptest[$i] := real_to_int(1000000.0 * sin(2.0 * ~NI_MATH_PI *1.0 * int_to_real($i)))
            inc($i)
        end while
    end function
     
  4. EvilDragon

    EvilDragon Moderator Moderator

    Messages:
    14,609
    If you have 128 elements, then your "frequency" needs to be 1/128. So instead of using 1.0, type (1.0 / 128.0).
     
  5. Lovechld2000

    Lovechld2000 NI Product Owner

    Messages:
    234
    aaaaaaaaah it's working. Thanks so much. I will keep your formula aside for other situations.

    Code:
    %tbl_poptest[$i] := 500000 + real_to_int (500000.0 * sin(2.0 * ~NI_MATH_PI *(1.0 / 128.0)* int_to_real($i)))
     
  6. EvilDragon

    EvilDragon Moderator Moderator

    Messages:
    14,609
    I'm not sure why are you adding 500000 there. Just multiply the whole sin() thing with 1000000.
     
  7. Lovechld2000

    Lovechld2000 NI Product Owner

    Messages:
    234
    without the 500000 it goes negative and half the plot is not shown. so 0 has to be 500000 with + or - 500000 amplitude yes? maybe you have a clearer way of seeing it? This works well. and having 2.0 gives you 2 sines. It's wonderful. I'm going to see if I can get the exp to work as well. Being able to produce a bunch of math in the tables is a great addition to ksp
     
  8. EvilDragon

    EvilDragon Moderator Moderator

    Messages:
    14,609
    Ahhh you need it unipolar. Gotcha.
     
  9. Lovechld2000

    Lovechld2000 NI Product Owner

    Messages:
    234
    well actually having half a sine wave is also useful so I might have a slider that lets you choose a bunch of shapes. V cool
     
  10. Lovechld2000

    Lovechld2000 NI Product Owner

    Messages:
    234
    full demo of shape making machine
    Code:
    on init     
        make_perfview
        set_ui_height_px(200)
        declare $i
        declare $logcalc
        declare $smjog
        kbutton(poptest_jog_hor_l,"",79,50,25,75,"")
        kbutton(poptest_jog_hor_r,"",405,50,25,75, "")
        kbutton(poptest_jog_ver_u,"",435,50,25,25, "")
        kbutton(poptest_jog_ver_d,"",435,100,25,25, "")   
        ui_tabler(poptest,128,    105,50,300,75,1000000)
        declare ui_slider $chooser (0,12)
    end on
    
    
    function create_shape
        select ($chooser)
            case 0
                $i := 0
                while ($i < 128)
                    %tbl_poptest[$i] := real_to_int (1000000.0 * sin(2.0 * ~NI_MATH_PI *(0.5 / 128.0)* int_to_real($i)))
                    inc($i)
                end while
            case 1
                $i := 0
                while ($i < 128)
                    %tbl_poptest[$i] := 1000000 - abs (real_to_int (1000000.0 * sin(2.0 * ~NI_MATH_PI *(0.5 / 128.0)* int_to_real($i))))
                    inc($i)
                end while           
            case 2
                $i := 0
                while ($i < 128)
                    %tbl_poptest[$i] := 500000 + real_to_int (500000.0 * sin(2.0 * ~NI_MATH_PI *(1.0 / 128.0)* int_to_real($i)))
                    inc($i)
                end while   
            case 3
                $i := 0
                while ($i < 128)
                    %tbl_poptest[$i] := 500000 + real_to_int (500000.0 * sin(2.0 * ~NI_MATH_PI *(2.0 / 128.0)* int_to_real($i)))
                    inc($i)
                end while
            case 4
                $i := 0
                while ($i < 128)
                    $logcalc := real_to_int (200000.0 * log ( 128.0 / int_to_real($i)))
                    message("")
                    if ($logcalc > 1000000)
                        $logcalc := 1000000
                    end if
                    %tbl_poptest[$i] :=  $logcalc   
                    inc($i)
                end while
            case 5
                $i := 0
                while ($i < 128)
                    $logcalc := real_to_int (200000.0 * log ( 128.0 / int_to_real($i)))
                    message("")
                    if ($logcalc > 1000000)
                        $logcalc := 1000000
                    end if
                    %tbl_poptest[$i] :=  abs(-1000000 + $logcalc)
                    inc($i)
                end while
            case 6
                $i := 127
                while ($i >= 0)
                    $logcalc := real_to_int (200000.0 * log ( 128.0 / int_to_real(abs(-127+$i))))
                    message("")
                    if ($logcalc > 1000000)
                        $logcalc := 1000000
                    end if
                    %tbl_poptest[$i] :=  $logcalc   
                    dec($i)
                end while
            case 7
                $i := 127
                while ($i >= 0)
                    $logcalc := real_to_int (200000.0 * log ( 128.0 / int_to_real(abs(-127+$i))))
                    message("")
                    if ($logcalc > 1000000)
                        $logcalc := 1000000
                    end if
                    %tbl_poptest[$i] :=  abs(-1000000 + $logcalc)
                    dec($i)
                end while   
            case 8
                $i := 0
                while ($i < 128)   
                %tbl_poptest[$i] := real_to_int ((1000000.0/128.0) * int_to_real($i))
                inc($i)
                end while
            case 9
                $i := 0
                while ($i < 128)   
                %tbl_poptest[$i] := abs(-1000000 + real_to_int ((1000000.0/128.0) * int_to_real($i)))
                inc($i)
                end while
            case 10
                $i := 0
                while ($i < 64)   
                %tbl_poptest[$i] := real_to_int ((1000000.0/64.0) * int_to_real($i))
                inc($i)
                end while   
                $i := 0
                while ($i < 64)   
                %tbl_poptest[$i+64] := abs(-1000000 + real_to_int ((1000000.0/64.0) * int_to_real($i)))
                inc($i)
                end while               
            case 11
                $i := 0
                while ($i < 64)   
                %tbl_poptest[$i] := abs(-1000000 + real_to_int ((1000000.0/64.0) * int_to_real($i)))
                inc($i)
                end while   
                $i := 0
                while ($i < 64)   
                %tbl_poptest[$i+64] := real_to_int ((1000000.0/64.0) * int_to_real($i))
                inc($i)
                end while   
            case 12
                $i := 0
                while ($i < 128)   
                %tbl_poptest[$i] := 500000
                inc($i)
                end while
        end select
        message("shape " & $chooser)
    end function
    
    function jog_poptest_hor
        if (btn_poptest_jog_hor_l = 1)   
            $smjog := %tbl_poptest[0] 
    
            $i := 0
            while ($i < 127)                                   
                 %tbl_poptest[$i] := %tbl_poptest[$i + 1]
            inc($i)
            end while
            %tbl_poptest[127] := $smjog   
        end if
        if (btn_poptest_jog_hor_r = 1)
            $smjog := %tbl_poptest[127] 
            $i := 127
            while ($i > 0)                                   
                %tbl_poptest[$i] := %tbl_poptest[$i - 1]
            dec($i)
            end while
            %tbl_poptest[0] := $smjog 
        end if
            btn_poptest_jog_hor_l := 0
            btn_poptest_jog_hor_r := 0
    end function
    
    function jog_poptest_ver
        if (btn_poptest_jog_ver_u = 1)
            $i := 0
                while ($i < 128)
                    %tbl_poptest[$i] := %tbl_poptest[$i] + 20000
                inc($i)
            end while
    
        end if
        if (btn_poptest_jog_ver_d = 1)
            $i := 0
            while ($i < 128)
                    %tbl_poptest[$i] := %tbl_poptest[$i] - 20000
                inc($i)
            end while   
        end if
        btn_poptest_jog_ver_u := 0
        btn_poptest_jog_ver_d := 0
        message("")
    end function
    
    
    on ui_control($chooser)
        call create_shape
    end on
    
    on ui_control(btn_poptest_jog_hor_l)
        call jog_poptest_hor
    end on
    
    on ui_control(btn_poptest_jog_hor_r)
        call jog_poptest_hor
    end on
    
    on ui_control(btn_poptest_jog_ver_u)
        call jog_poptest_ver
    end on
    
    on ui_control(btn_poptest_jog_ver_d)
        call jog_poptest_ver
    end on
    
    
    macro ui_tabler(#name#,elements,x,y,width,height,range)
        declare ui_table %tbl_#name#[elements](1,1,range)
        move_control_px(%tbl_#name#, x, y)
        %tbl_#name# -> WIDTH := width
        %tbl_#name# -> HEIGHT := height
        make_persistent (%tbl_#name#)
    end macro
    
    macro kbutton(#name#, #image#, x, y, width, height, #text#)
        declare ui_button btn_#name#
        btn_#name# -> TEXT := #text#
        btn_#name# -> POS_X := x
        btn_#name# -> POS_Y := y
        btn_#name# -> PICTURE := #image#
        btn_#name# -> WIDTH := width
        btn_#name# -> HEIGHT := height
        make_persistent(btn_#name#)
        read_persistent_var(btn_#name#)
    end macro
     
  11. corbo-billy

    corbo-billy NI Product Owner

    Messages:
    515
    awesome: many thanks _
     
  12. Lovechld2000

    Lovechld2000 NI Product Owner

    Messages:
    234
    you need sublime for this version, if you would like to see a compiled version let me know
     
  13. corbo-billy

    corbo-billy NI Product Owner

    Messages:
    515
    Yes, I realized it and it's OK at home to use Sublime Text 3 and transmit to Kontakt.
    I was able to work with my pictures, for controls: I appreciate the approach because it helps me to understand a little more in depth, these concepts because I don't have the usefulness of these functions.
     
    Last edited: Apr 7, 2019