Best way to handle slowing volume?
Jeff
Posts: 374
I'm controlling a Nexia tc Audio processor in a room. I've got two bargraphs on my touchpanel, one is display only and shows the audio level in the room. The other one is completely transparent and laid on top of the display level, and is the actual input device.
If I just set up a level event that sends the volume to the nexia every time a level event occurs, it sends way too many events and the nexia gets several seconds behind, it literally can't keep up with all the information i'm sending it. The obvious solution is to only send the level a few times a second.
I've figured out a way to do it, using a timeline, which seems a bit cumbersome, but I couldn't figure out how to check the status of a wait. Is this really the best way to accomplish this? Or is there a better way to do it that doesn't involve setting up a timeline?
If I just set up a level event that sends the volume to the nexia every time a level event occurs, it sends way too many events and the nexia gets several seconds behind, it literally can't keep up with all the information i'm sending it. The obvious solution is to only send the level a few times a second.
I've figured out a way to do it, using a timeline, which seems a bit cumbersome, but I couldn't figure out how to check the status of a wait. Is this really the best way to accomplish this? Or is there a better way to do it that doesn't involve setting up a timeline?
define_constant VolTL = 3 define_variable volatile long lVolTime[1] = 200 define_event //Main Page Events //Volume Control button_event[dvTP,17] { push: { on[nVolumeActive] } release: //nVolumeActive basically means that level events dont get triggered because the panel dropped offline, only if you actually touch the volume bar { off[nVolumeActive] if (nVolume<75) //When you take your finger off, we send a final volume for where you ended up { send_string dvBiamp,"'SETL 1 OUTLVL 14 1 0 ',10" send_string dvBiamp,"'SETL 1 OUTLVL 14 2 0 ',10" } else { send_string dvBiamp,"'SETL 1 OUTLVL 14 1 ',itoa(nVolume*5),' ',10" send_string dvBiamp,"'SETL 1 OUTLVL 14 2 ',itoa(nVolume*5),' ',10" } } } level_event[dvTP,17] //This is a level that you can't see layered on top of the visual one { if(nVolumeActive) { nVolume=level.value if (!timeline_active(VolTL)) //If you've sent the level within the last fifth of a second, don't do it again { if (nVolume<75) { send_string dvBiamp,"'SETL 1 OUTLVL 14 1 0 ',10" send_string dvBiamp,"'SETL 1 OUTLVL 14 2 0 ',10" } else { send_string dvBiamp,"'SETL 1 OUTLVL 14 1 ',itoa(nVolume*5),' ',10" send_string dvBiamp,"'SETL 1 OUTLVL 14 2 ',itoa(nVolume*5),' ',10" } timeline_create (VolTL,lVolTime,1,timeline_relative,timeline_once) } send_level dvTP,1,nVolume //Show the volume on the touchpanel } }
0
Comments
Having said that, it might be a good idea to send commands that volume ramp up and down as appposed to descrete volume commands. (Assuming the gear can do this)
Most devices will ramp themselves up or down on their own. All you need do then is track the descrete volume feedback and send it to the fader. It will involve you putting some kind volume up or down buttons.
Another thing you can do is track the volume fader data being sent when the user adjusts the fader on top, but don't send the data to the device until they releases their finger. That way you won't send a bunch of intermediate volume changes. The down side of this is that they can be moving the fader up but not hearing the volume change, so they keep going higher and higher. ONce they let go, they might get a rather sudden jump in the volume.
Just a couple thoughts.
I used to like the idea of the client adjusting the fader themselves but soon tired of the problems this sexy interface caused with slower gear. I eventually gave into the more quaint notion of just giving them a volume up and down button and leaving the fader as simple feedback. It is reliable and doesn't confuse the client.
I just swamp the Nexia with volume information when a user uses the barpgraph to adjust to volume. It doesn't happen alot (maybe once or twice during a meeting).
Sending the final volume on releasing the bargraph helps to make sure you are actually on the wanted volume.
You could use the ramp commands by adding code to check what direction the user is going, Up or Down with a timer to check for a period of time that the user has stopped ramping the bargraph. Then you can send the Stop Ramp. If the user goes up/down/up/down and so on, it will just ramp up/down until they either "Release" or hold their finger in the one position. This would then be minimal commands being sent.
Maybe you can reduce the range your ramping from. Instead of -100dB to +12 maybe try -50dB through 0dB
Biggest issue I have with the nexia's is having only the last 10% of the volume bar being usefull (-100 to 0db ramping).
I'd love to do some kind of logarithmic volume scale but not sure how to do that.
I'd rather keep the bargraph than add + and - buttons. Changing which ramp command I send based on which direction the user is going doesn't really acknowledge where in the bargraph the person has selected.
I mean, all of those suggestions will get the job done, but I don't see them being any more effective than what I wrote above. In fact, I think the trick with the timeline, which basically means it wont send the level more than once every 5 seconds, is more effective than everything except the individual volume buttons.
Assuming I'd rather send discrete volume commands than try to guess ramping correctly, is there a better way in code to accomplish what I'm doing? The timeline just seems clunky, with the requirement for a declared constant and long.
J
if you only send volume change every 5 seconds, the user will get confused. He ramps the volume bar up, and has to wait 5 seconds before he finds out if the volume is too loud or too soft...
From the nexia manual:
the FDRLVL command excepts the 'SET' commando, as well as INC/DEC
You could use the INC/DEC commando's to raise the volume, and then process the incoming volume string to display your feedback
Wait 2 (or minimum time to send strings)
{
If (VolumeIsUp && Volume <= MaxVolume)
{
Volume++;
Send_String YourDevice, "String with Volume";
{
}
Same for Volume Down.
This will then only send the string with the wait time for the device when the user is pressing the button.
If I switch to using Inc/Dec to control the volume, what happens when a user just presses the volume bar someplace nowhere near where the volume is? Does it just ramp a little bit? Or does it ramp all the way up there?
I'm intrigued by the mainline code variant, that could be fun to play with.
J
In the spirit of not using mainline for much you could just do this with a hold event
BUTTON_EVENT[DVTP,VOLUP]
HOLD[2,REPEAT]:
{
If (VolumeIsUp && Volume <= MaxVolume)
{
Volume++;
Send_String YourDevice, "String with Volume";
{
}
This takes care of sending the volume only five times a second once you've touched it and held for at least a 5th of a second, but it doesn't do anything the first time you touch it. Under this code, its entirely possible to just tap it once and have nothing at all get sent to the Biamp. If I put the send to the biamp under the Push operator, I wont have time to get nVolume from the level_event . . .
Any idea on how to fix that one? Maybe another flag or something so that the level event itself sends the volume command to the biamp the first time its triggered since it has last been touched?
J
I'm beginning to agree with you, but thats really not an option for me in this case. I'm not a very good graphic designer, and the guy who did this design has since left the company. I'd have to hire someone to redo the design to fit in additional volume up/down buttons, which I don't expect to happen. There's just not enough space where the volume bar is to add in up/down buttons right now, so it'd involve some significant redrawing.
For future designs, however, I'll probably be going to buttons with a display level.
J
you can have the push operator fire an event, just add it there If someone taps the button, the volume gets sent. If someone holds the button, it only gets sent every 5th of a second
J
Its getting set the LAST time I touched the bar graph. So for example, I drag the bar graph all the way down to the bottom. I take my hand off. nVolume is now 0. Then I tap the bar graph about halfway up (lets pretend I tap exactly at 50). My understanding is things happen in this order
1. Push Handler fires
2. nVolumeActive is set to 1
3. nVolume(0) is sent to the Biamp
4. Level Event Fires
5. nVolume is set to 50
6. Release Handler fires
7. nVolume(50) is sent to the Biamp
Under that order, there's no reason to send in the push handler. Now that I look at it, though, that shouldn't be a problem, as long as the level event ACTUALLY fires inbetween the push and release handlers. Is that a fairly safe assumption?
J
i guess it is
like i said: i don't use 'slowing' of the volume, and all my nexias still work
Thanks a ton guys, I'll try testing this out sometime this week.
J