What's new

Simulated LED VU meter problem [solved]

tonewill

Active Member
Hello,
I'm working on simulating LED VU meters and it's going okay expect for a problem I've just noticed. The label graphic has 19 animations. Here's some basic on note code:
Code:
on note
    channel := note_to_channel[EVENT_NOTE]
    if channel # -1
        for vu_level[channel] := ((EVENT_VELOCITY * 19) / 128) downto 0
            vu_label[channel] -> picture_state := vu_level[channel]
            wait(30000)
        end for
    end if
end on
The problem happens when the same note is played before the loop has finished the previous note. This causes the loop to run twice as quickly presumably because there are now 2 loops setting the picture_state.
I've tried messing with storing and comparing NI_CALLBACK_ID and EVENT_NOTE but without luck. What's the best way to handle this please? Many thanks.

PS: These are percussion sounds so I don't want the meter to hold while a note is pressed in case you noiticed that.
 
Last edited:
OP
T

tonewill

Active Member
Thanks a lot for the suggestion. As often happens, just after I posted it struck me what I was doing wrong when I tried checking the callback ID. I need an array of them, one for each note and that (almost) solved it. Only case it didn't solve was when two different notes (or more) trigger the same graphic.

Code:
    callback_id[EVENT_NOTE] := NI_CALLBACK_ID
    if note_to_channel[EVENT_NOTE] # -1
        for vu_level[note_to_channel[EVENT_NOTE]] := ((EVENT_VELOCITY * 19) / 128) downto 0
            vu_label[note_to_channel[EVENT_NOTE]] -> picture_state := vu_level[note_to_channel[EVENT_NOTE]]
            wait(30000)
            if callback_id[EVENT_NOTE] # NI_CALLBACK_ID
                exit
            end if
        end for
    end if
EDIT: Can use EVENT_ID instead if NI_CALLBACK_ID, don't know if one has something over the other in this case.
 
Last edited:
OP
T

tonewill

Active Member
Sorry, I'm missing something, can you explain a little more? The graphics animation must respond to note on events, so why is the listener callback preferable, doesn't it just get called at specific intervals?
Thanks for any help.
 

EvgenyEmelyanov

Composer | Programmer
Because using listener callback, you can do parallel cycles. Plus, it's better to keep the note callback more clear.

You can use a flag variable and set it to 1 when you trigger a note to reactivate the animation.

The idea is:

Code:
on note
   flag_1 := 1
   flag_2 := 0
end on

on listener
  if(flag_2 = 1)

    {CONTINUE THE ANIMATION}

  end if

  if(flag_1 = 1)
   
    {START THE ANIMATION FROM SCRATCH}

    flag_1 := 0
    flag_2 := 1
  end if
end on
 
OP
T

tonewill

Active Member
Thank you, much appreciated. I have 15 separate LED type graphics (like a mixer) depending on the note so it's a little more involved. Currently, since my last post I have it working perfectly in the note callback so it's hard to not just leave it and move on but I'm interested in trying the listener method so will look into it tomorrow, had enough for today.

I should point out I'm handling all this in the note callback of the last script of the chain, don't know if that makes it better.

Thanks again.
 

sndmarks

New Member
Where might one look to learn more about this type of programming? And is this the same type of thing used to create "virtual analog" and modeled synths?
 
OP
T

tonewill

Active Member
After playing around with using on listener as suggested, I like it a lot. The label has 20 animations that indicate the level of a slider with range of 0-1000000 in this test. If I'm doing it wrong or can improve it please let me know.

Code:
on init
    message("")
    make_perfview
    set_ui_width_px(633)
    set_ui_height_px(200)

    declare ui_label vu_label(1, 1)
    vu_label -> picture := "vu_label"
    vu_label -> text := ""

    declare ui_slider volume_slider(0, 1000000)

    set_listener(NI_SIGNAL_TIMER_MS, 25000)
end on

on listener
        if vu_label -> picture_state > 0
            vu_label -> picture_state := vu_label -> picture_state - 1
        end if
end on

on note
    vu_label -> picture_state := volume_slider * 20 / 1000000 - 1
end on
PS This is for percussion sounds so "LED" shouldn't stay on for note duration like a sustained sound. Thought I should point that out again.
 
Last edited:
OP
T

tonewill

Active Member
Is it a bad idea to have a loop in the listener callback that checks an array of 15 labels to see if their picture state is 0 and decrements them if not? The listener is set to 30000 microseconds. It works alright but the loop must be going continually while the instrument is open. Is there no way to start and stop the listener when needed?
 

EvilDragon

KSP Wizard
That should be fine. What you could do is have a flag if all the picture states are 0 and then restrict that while loop from triggering at all.
 
OP
T

tonewill

Active Member
Thanks very much E.D, I added a flag like you suggested and all working fine. Thanks again.
 
Top Bottom