Forum: General Discussion
If you need extended support, contact our Support Team.
(*) The moderators hold the rights to move or modify posts in order to keep the discussions clear or to facilitate the search.
Tema: Script School - Page: 1
VDJscript is the language in which all commands in VirtualDJ 8 are written.
It is used in skins, keyboard shortcuts,controller mappers and many plugins
It is the absolute key to customisation.
So here it is, my aim is to write a few tutorials going into beginner level detail but also helping anyone who wants help* (if your script is very complicated & you have a proficient script ability & your problem doesn't interest then I'm sorry you're on your own or you can pay for my services)
I'm here to teach so I may not always give you the complete solution you want, but will give you an example to help you work it out for yourself.
Reading list, (yep I said school)
Here is atomix's script tutorial
It actually covers pretty much everything but it is really consise, tricky for a beginner but I recomend reading several times as you learn script here.
Here is the list of verbs, these are the words you will start to think in once you practice enough, in scripting you'll go back to it time & again. And you should.
Here is the users script database, many are my entries, if there's anything you don't understand, copy and paste here and we can talk about it.
Mensajes Sat 19 May 18 @ 12:28 pm
This may surprise you the actual script syntax isn't the hardest bit about writing robust fool proof scripting.
As a beginner yes the syntax isn't easy but after a short amount of time it's just like learning a word for the day, use the word a few times and you just remember.
The hard bit of scripting is breaking down your problem into the smallest steps possible, thinking I want this to do that might seem clear to you but then when you look at every detail or possibility i gets hard
With any script that you can't just think in your head it is best to write in plain english what you want (i still do this for complicated stuff)
Right this will introduce critical thinking and how to make multiple queries.
A simple question that if you just question Is it raining? Yes it is get me an umbrella : no it isnt, i don't need one.
So now its raining and you're sat in your house going nowhere holding a brolly looking a wally.
Let's try again
Is it raining ? Yes it is but do i need to go outside? Yes i do get me a brolly : no i dont need to go outside, a brolly isn't needed : no it isn't raining no brolly for me thanks
Lets look at that as logic
All logic questions have only two possiblecanswers yes/no, 1/0, on/off and script queries need to know what to do in either case
Ask a 1st question get a yes answer as part of the yes answer ask 2nd question get a yes answer, get a brolly : get a no answer to the 2nd question, no brolly, get a no answer for the 1st, no brolly
Thats how vdj script queries work, once all questions have been answered and acted on the script is finished
Ok enough of brollys, a real script now,
Imagine you have only two tracks bpm sync'd that aren't playing, you have only 1 button to start the beat and want to keep the beat going forever, we'll let the out going track play to the very end so vdj stops it and sends it back to the start.
If deck 1 and deck 2 is playing do nothing
If deck 1 is playing on its own start deck 2
And to start if deck is playing start deck 1
So the real script will look like this
deck 1 play ? deck 2 play ? nothing : deck 2 play : deck 1 play
That will do for this lesson more to come.
Mensajes Sat 19 May 18 @ 2:03 pm
A query always starts with a verb and is asked with a question mark " ? "
A query always has 2 possibilities, true or false.
(other ways of saying true or false could be 1 or 0, you could also say on or off)
the true and false replies are seperated with a colon symbol " : "
As should be obvious from previous posts verb (commands) are linked together with the " & " symbol.
There is a special case for queries when you want to only do one thing if both two are true, if only one is true or neither is true we do another thing. we do this by linking the commands with " && "
You have 1 button on a pad or controller button,
You have a track playing and you've discovered a certain bit sounds good if you apply echo and flanger, it also sounds good to brake (as in turntable wind down) out of the track.
Ok one button, it first needs to turn the echo and flanger on, and your second press needs to call the brakestart fx, BUT perhaps you turned the echo and flanger on via the mouse or action poi(action poi lessons to come much later)
Maybe only one of the fx is on
So the script looks like this
effect_active "echo" && effect_active "flanger" ? effect_active "brakeStart" : effect_active "echo" on & effect_active "flanger" on
Are both fx on ? Yes, call the brake : no not both are on, turn both fx on
Notice that I used ' effect_active "flanger" on ' the on bit is important, all we know is that it is not true that BOTH fx are on.
neither could be on then 'effect_active "flanger" would be ok as this command toggles the fx (if on turn off, if off turn on)
But if one fx is on the toggling action is no good, so we include " on " so vdj knows what we want.
Ok let's expand that a little so if you press the button after the brake has stopped the track it turns the echo and flanger off (so you can load and cue your next track, whatever)
play ? effect_active "echo" && effect_active "flanger" ? effect_active "brakeStart" : effect_active "echo" on & effect_active "flanger" on : effect_disable_all
If playing do all the stuff we've covered, if not playing turn all the fx off.
Just about finished, just wanting to add " on " and " off " can be very useful if you if you know you want an fx on and don't want to query it to avoid toggling.
Look at that I started on queries and moved into fx stuff, I suppost everything fx next then.
Mensajes Wed 23 May 18 @ 7:58 am
I had some luck with a similar script which queries the BPM of the masterdeck, then uses a little algebra to set a variable used to cut the level in and out on the actiondeck. The difference being it incorporates a one-time query of a masterdeck state, rather than a constant query. And I think that's where I'm lost in the woods, how to keep the repeats on the decks(or device sides) intended.
I'm not on my testing machine right now, but I will post an edit later today with the scripts in question so you can see exactly what I'm doing.
Once again Loco, thank you for this. Our community is a better place because of knowledgeable contributors like yourself.
Mensajes Wed 23 May 18 @ 10:38 am
adjust_cbg : adjust the beat grid. 'adjust_cbg +2' moves the cbg & first beat 2 whole beats.
'adjust_cbg +10%' moves the actual bars.
The GridAdjust pad page contains many scripts involved with the cbg
As of getting it mapped to a jog wheel, I'd have to see the current script on the wheel.
Mensajes Tue 29 May 18 @ 9:48 am
I will answer every request for help, but after a time, I'll request they are raised and I'll add them to a lesson.
Mensajes Tue 29 May 18 @ 6:34 pm
Moving on to FX
First a word about fx slots, what are they and why do we have then.
Imagine you had some sort of mega controller that had many many dials, that would be cool in a way, every dial could do just one job.
You could just script the hw dial directly to the sw dial of your choice, something like this
effect_slider "echo" 1
So your hw dial always controls the first slider of the echo fx.
But such a controller doesn't really exist.
So we need to have fx slots so the hw dial can control different sw dials depending on what we are doing.
The default skin can show 1 or 3 fx slots BUT as with many things in vdj, just because it isn't on the skin doesn't mean you can't use it (imagine using a 2 deck skin and a 4 deck controller, you can still use decks 3 & 4 even though they are invisible, ninja)
So any way a usual script on a controller dial for a fx slot slider is like this
effect_slider 3 2
We want to control a slider on the 3rd fx slot and we want it to be the 2nd slider.
Ok lets expand on what we know and learn about what parameters various scripts can take.
[1st optional param is slot number]
[2nd optional param is fx name in quotes " "]
[3rd optional param is on/off or 1/0]
If you don't specify a slot but specify a name the fx doesn't get a slot. It still works
If you specify the 1st & 3rd it will turn the slot given on or off
If you specify the 2nd only, it will toggle the fx regardless if it is on a slot or not
If you specify the 1st & 2nd, it will put that effect on that slot and toggle it.
If you specify 2nd & 3rd it will switch the fx to the 3rd regardless if it is slotted or not.
If you specify just the 3rd then vdj doesnt know its the 3rd param, its only seen one param so it asumes its the 1st
I'm going to write up more on each of the effect_X scripts and the params they can take, but for now that will do.
Mensajes Tue 29 May 18 @ 6:36 pm
<map action="var_equal '$shift' 0 ? touchwheel_touch : nothing" value="JOG_TOUCH"/>
<map action="var_equal '$shift' 0 ? touchwheel : param_smaller 0 ? adjust_cbg -1% : adjust_cbg +1%" value="JOG"/>
Above is an extract from a controller mapping. Originally the jog controlled the sampler volume. I did not need that and so adapted the script for cbg adjustment. It was a case of monkey sees and does. I don't understand why '$shift' 0 is used instead of '$shift' as in the first line of the mapping extract.
It does work on my controller.
Since recently changing my sub controller I've had enough buttons to do pads, samples and more. Hence I've only just started using pads so I overlooked your useful addon. Mind you I could have put it on my keyboard. I brought this issue up because rapid cbg adjustment has become more and more important.
Note You can put this script on any available endless encoder.
Mensajes Wed 30 May 18 @ 7:21 am
<map action="var_equal '$shift' ? nothing : touchwheel_touch" value="JOG_TOUCH"/>
<map action="var_equal '$shift' ? param_smaller 0 ? adjust_cbg -1% : adjust_cbg +1% : touchwheel" value="JOG"/>
BTW: For MOST controller the above scripts can be like this from version 8.2 onwards:
<map value="KEYLOCK" action="key_lock" />
<map value="SHIFT_KEYLOCK" action="beat_tap" />
<map value="JOG_TOUCH" action="touchwheel_touch" />
<map value="SHIFT_JOG_TOUCH" action="nothing" />
<map value="JOG" action="touchwheel" />
<map value="SHIFT_JOG" action="adjust_cbg" />
Mensajes Wed 30 May 18 @ 7:40 am
not including a value in the first is just a short hand, sometimes vars are used as on/off flags (like $shift is) and no value, querying >0 is fine
Other times when a var has several possible values it is better to query against a number, but no number queries in some circumstances may be useful.
1 guess is the jog wheel script queries
var '$shift' 0 ?
So the true/false replies are in an order to make more sense to beginners
I'm just using the jog, the first reply is that,
I'm using the jog with shift, the second reply is this.
More likely it could be just down to how the mapping was written,
The atomix hardware guys have done loads of mappings and won't work as a user does, (mapping insided vdj one command at a time) no they'll do it all in np++ the whole mapping in one go and then test in vdj
Just one of those things you do to be efficient.
Touching the jog without shift will always just script to touchWheel, but with shift the function may change or the values may need to be tweaked, therefore it's easier to have the bit that may change at the end of a script, instead of having it as the 1st reply, somewhere in the middle of the script.
Edit, thanks phantom.
ah yes v8.2 now creates shift+entryName entry names, it does make life easier.
Mensajes Wed 30 May 18 @ 8:00 am
..and thxs Locodog.
Mensajes Wed 30 May 18 @ 8:00 am
Mensajes Wed 30 May 18 @ 6:22 pm
These do a similar action except one small difference.
Say you have an effect actually on and running on slot 1, say reverb.
If you use the script " effect_select 1 'echo' "
It will do 2 things, first it will turn off the fx currently on slot 1 (we said reverb), second it will put the echo fx on slot 1 but the echo will not be on,
If you use the script " effect_select_multi 1 'echo' "
echo will go on slot 1, (again still not on) but the fx on slot 1 (reverb 'member...?) As before echo will not be switched off.
Right since they are so similar I'll only cover the params for effect_select, multi performs the same.
[1st optional param is slot number]
[Alternative 1st param can be "video" in quotes to change in the video fx slot]
[2nd optional param is fx name in " "s]
[Alternative 2nd param can be a number, 0 will take you to the very first fx you have in your list, 1 will go to the last fx, if you include a + or - it will move from the current position]
Example effect_select 3 +1, move down the list 1 item for slot 3
If you use effect_select on it's own then a popup for slot 1 will appear and you can use your browser encoder/browser button to pick a fx (keyboard up/down arrows + enter work too)
If you use effect_select 2, it will popup for slot 2
If you use effect_select "echo" echo will go on slot 1
If you use a slot number and fx name the fx goes on the chosen slot
Effect_select (and multi) is useful to get fx on slot so you can check sliders are ok before starting it with effect_active (we've covered this)
But in some cases you don't need to check the sliders as you can script all the sliders and buttons to your perfect settings, (buttons & sliders covered in maybe 2 lessons time)
Right then next lesson will be a real world example of how I select fx from my launchpad, the mistakes I made, how I got around them.
Later still i will write how I will rewrite the mapping when i start from scratch. But we'll have to cover the basics of variables first.
Mensajes Mon 04 Jun 18 @ 1:36 am
Variables are how vdj remembers numbers, previously in vdj your shift button toggled a variable either 1 when pressed 0 when released.
After a time vdj simplified this variable to a single verb
We see shift, deep under the hood of vdj it sees
'$shift' ? Yes : no
Back then to get a shift & button to give you a different result you had to query the variable.
Say you wanted to have shift + play = reverse
Originally your buttons are mapped as so
Button; Play, Mapping; play
Button; Shift, Mapping; shift
So to get the result you want you need to change the play mapping to
shift ? reverse : play
Query the shift variable value = 1, if true reverse, if false play.
Vdj has changed now that if you press shift + play, it will create a new mapping entry called shiftplay.
It makes life easier for sure, but when i started mapping my gear it wasn't available, the old way still works today and I'm going to go thru how i mapped back then.
Ok let's see something practical...
In the empire of dirt here, I've a run of the mill mid range (old) controller but this isn't about that.
I've also got launchpad2 (it's about this,)
My goto pad is one I developed myself.
The bottom 8*4 pads call effects in various ways
The first row has fx for slot 1
The 2nd row for slot 2
3rd for slot 3
The last row of 8 just toggle fx, no slot number needed,
I generally just toggle the fx on and send it to a slot with something like this, slot number, fx name.
effect_active 2 "flanger"
So row 1 button 1
I put the hi pass filter
effect_active 1 "filter hp"
Row 1 button 2
I put the low pass filter
effect active 1 "filter lp"
I filled a lot of buttons with fx until i spotted a problem.
I'd like to use both the hp and lp filters at the same time.
I could move to a different row but i would be changing the mapping all the time when I'd notice I like this fx with another fx, and that gets tricky to remember whats what.
So i decided I'll keep the originals and add a copy of lp filter to another row.
effect_active 2 "filter lp"
But now I've a new problem, what if I had lp filter on and active on slot 1 and I want to use hp filter on slot 1 and move the lp filter on slot 2.
If i just use effect_active 2 "filter lp"
Then sure the fx goes to the slot but it gets turned off.
I need to use effect_select_multi
I need to change my mapping.. ok I'll use shift+row2button1 to do it
So my mapping now looks like this
shift ? effect_select_multi 2 "filter lp" : effect_active 2 "filter lp"
Very good with normal press i can get the fx on slot and toggle on/off, with shift pressed i can get fx on slot without toggling.
Thats it is it? Oh no, that hasn't covered every eventuality, i can send the fx to slot, and send to slot and toggle, what about if i had the fx running on slot and used another fx on that slot, thus kicking the lp filter off the slot? How do i turn it off?
If i normal press the fx will turn off sure but then that will kick out whatever else was on slot at the time, I'd be making work for myself.
For normal press I need to query if the fx is running, if running turn the fx off : if not running send to slot and turn the fx on.
And that looks like this
shift ? effect_select_multi 2 "filter lp" : effect_active "filter lp" on ? effect_active "filter lp" off : effect_active 2 "filter lp" on
The on & off 's aren't needed (toggling would be fine for the switching and if ommited from a query vdj assumes you are asking "is it on?" i just added them to help you read it
Is shift pressed? Yes, so we want the fx back on slot without toggling the fx or turning the other fx on slot off : not shifted, is the fx active ? (We don't use a slot number, it may be on this slot or another slot or no slot, all we want to do is to switch it off)
Yes its active, turn it off : no its not active, bring it to slot and turn it on.
This is reasonable strong scripting, cover all possibilities and it will work reliably every time.
Now this was all organic, the problem as i see it I'm wasting buttons, when i start from scratch I'll have a better system that uses variables and then every button will control a different fx and I'll be able to send them to any slot, but that's another lesson.
(might link the fb crowd in now)
Mensajes Thu 07 Jun 18 @ 4:04 am
Mensajes Thu 07 Jun 18 @ 9:52 am
Thanks for a really interesting and useful thread!
Quick question on the new 'Shift' function... with the old scripting I think a distinction was made between a global '$shift' variable and a deck specific 'shift'..... is it possible to make this distinction with the new system or is it always deck specific?
Mensajes Thu 07 Jun 18 @ 11:21 am
Again local shift per device side is sonething set by the def file and i think its not used anymore
I think you could have shift per side with device_side and local variables but it would be a step backwards in my opinion, unless you have an interesting reason why you want local shift, then I'm all ears
Then there's hardware shift but that reconfigures the hardware to send completely different midi messages
Mensajes Thu 07 Jun 18 @ 11:37 am
MrJackson2014 wrote :
Just saying this thread is amazingly interesting and I learn a lot, thanks Loco !
I agree :)
Mensajes Thu 07 Jun 18 @ 12:05 pm
Next is effect_buttons and effect_sliders, and the practical bit is something I don't think anyone else does.
Mensajes Thu 07 Jun 18 @ 4:37 pm
If you've read the previous lessons this first bit should be easy.
Has 3 possible params
1st optional param, Slot number
Alternate 1st, optional, "FxName" in quotes
2nd optional, Button number
3rd optional On/Off
'effect_button 1 2' button 2 on slot 1.
'effect_button 2' button 2 on slot 1,
if vdj doesn't see a 1st then it assumes slot 1
if vdj doesn't see a 1st & 2nd then it assumes slot 1 button 1
'effect_button "echo" on' 1st button of the echo fx to on
if vdj doesn't see a 2nd then it assumes button 1
Effect_slider is very similar, but before i repeat myself, lets briefly go thru how vdj script gets values from hardware sliders.
You turn a hardware slider, and it sends a midinote and a value, the first thing that happen inside vdj is it runs this thru a definition file,
The def file first gives a name to a midinote, thats the name you see in mapping, it then translates the value sent to a vdj value, old midi sends values from 0 to 127 (7 bits precision for binary fans), and vdj usually scales these from 0 to 1.0.
So after that is done under the hood it passes the name and translated value to the mapper file,
We've skinmed def files (there be dragons here) and we're back to mappers, the bit we're used to.
So we've turned a dial to, lets say filter dial to half, the info that gets to the mapper is, something called filter has been set to half, then we need a script to actually instruct vdj what to do.
The dial may be called filter but until the mapper script says that controls vdjs filter it does nothing.
And as you can see from a filter dial mapping, it just says filter.... where does the the value come in?
Well what happens is any script that accepts value parameters has the value stuck on the end of it.
So stupid example here lets say you map the dial named filter to "filter 75%" (stupid, a waste of a dial)
Using our hardware example (filter dial, half way)
Vdj sees "filter 75% 50%" (hardware value stuck on the end)
Since the filter script only accepts one param, the 50% doesn't mean anything so vdj ignores it.
....going slightly off track here, but remember the hardware value, (known as the implicit value) is always tacked on the end of the script, if it makes sense in the script it's used, if it doesn't it's ignored.
Back on track effect_slider, very much like button above
1st optional slot number
Alternate 1st optional "fx name"
2nd option slider number
3rd optional value.
Values can be written in a few ways the 2 most common are % (from 0 to 100 & you can also have 1.5%)
The other common way is between 0.0 and 1, there are other ways but i dont think many people use midi 0-127 or the other one 0-4095.
Values can be definitive, " filter 1.5%" will set the filter @ 1.5%
Or thet can be relative " filter -1.5%" will move down 1.5% from where the it was before.
Why would you want a slider to be given a preset value?
Well as you know, when using effects you generally start the fx with subtlety, then as you're building up to whatever you can push it to extremes, this works some of the time. But what happen after you have turned the fx off and want to use it again? The settings are still at the extremes.
So let's use script to save us some work
Lets say you like to start echo with a strength at 20%
effect_active 1 "echo" & effect_slider 1 20%
Works ok for switching the fx on, but on the second press to turn it off it will mess with the slider again and that might ruin the trailing echo tail you had set up.
Let's think we need to use queries to establish are we turning the fx on or off, so only when we switch on do we want to set the strength.
Take a second, by now you should be able to say the script needed in your head.
effect_active "echo" off ? effect_active 1 "echo" on & effect_slider 1 20% : effect_active "echo" off
Ok that is probably a little different to what you thought, firstly i queried is echo off, i did this because our monkey brains like to have things ordered "turn on first turn off second"
So querying off first is how we see problems in the real world.
Next i didn't use the fx name to set the slider, well we know the echo is on slot 1 we just put it there, so no need.
3rd thing to turn the fx off i used the fx name not the slot, why?
Well as we've seen in the previous lesson, it may be on slot or another or none, while using the slot number will work if you keep everything simple, forever. As your mapping grows so will the complexity. We just want echo off and no matter what changes happen in the future, if echo is on, this button will turn it off.
Gone on for too long on this one, next post is something practical with why you'd choose fx with no slots, and why i love & how i use the loop roll fx.
Mensajes Sat 09 Jun 18 @ 6:14 pm