Forum: General Discussion

About VirtualDJ and DJing in general

If you need extended support, contact our Support Team.
Forum Guidelines  (*) The moderators hold the rights to move or modify posts in order to keep the discussions clear or to facilitate the search.
Topic: Script School - Page: 2
RanikiPRO InfinityMember since 2018
Hi Locodog,

Thanks for the reply to my 'shift' query...

I've got some further questions on this but I'll post them as a separate thread so as not to use up bandwidth on this thread....

Posted Sat 16 Jun 18 @ 11:06 am
locodog wrote :
Sure but let me ask you...

You are correct in your assertion but the question is what happens when two or more effects are on and active on slots? What about if nothing is active?
How do you pick?

Actually 2nd question, what controller are you using? I can look at the mapper myself.


sorry I took so long to reply

I am using the Vestax VCI 400.

I actually did not think of combining effects as i anticipated that i would be using one effect at a time and the knobs would have been used only for the effect parameters for now.

Posted Mon 02 Jul 18 @ 3:17 am
locodogPRO InfinityModeratorMember since 2013
wrote :

wonder if you would mind covering this in your next post. I have three buttons on which i can assign three different effects, but i would like the knobs to control the parameters of which ever effect is active at the time.

So if i activate the second effect, i want the three knobs to control the parameters of that active effect.

effect_active 1 ? effect_slider 1 1 : effect_active 2 ? : effect_slider 1 2 : effect_active 3 ? : etc etc etc Can I use the term effect_slider 1 1 to indicate that I want the knob to control the first parameter of the effect in slot 1

How would I go about writing such a script?

VCI 400 looked a solid controller years ago when I was looking, it must be soild if it's still going today.

Ok looking at it, this is for dial 1
first you query if the slot is active, if yes effect the slider as you have said, if false query the second slot, if yes do the slider , if false query the third slot and if true do the slider,

effect_active 1 ? effect_slider 1 1 : effect_active 2 ? effect_slider 2 1 : effect_active 3 ? effect_slider 3 1 : nothing

the problem is you have no control of fx dial while they are switched off. so what I would do is use shift+dial to set a variable so vdj can control the dials on the slot of your choice even if all slots are off so your first dial will look like this

shift ? set "@slotVar" 1 : effect_active 1 ? effect_slider 1 1 : effect_active 2 ? effect_slider 2 1 : effect_active 3 ? effect_slider 3 1 : var_equal "@slotVar" 1 ? effect_slider 1 1 : var_equal "@slotVar" 2 ? effect_slider 2 1 : var_equal "@slotVar" 3 ? effect_slider 3 1 : nothing

so if no slot is active a quick press of shift and twist dial 1 and slot 1 makes the variable = 1, it tests if any slot is active, if none are then the query
var_equal "@slotVar" 1 ? is true so control slot 1

your other 2 dials start
shift ? set "@slotVar" 2
shift ? set "@slotVar" 3
of course changing the 2nd param (slider number) of effect_slider [slot#] [slider#]

we use persistant variable (the name starts with @) so when you close vdj the var is remembered for next session, and because of the order we wrote the script, active slots always have priority.

Now you have control but no visual feedback, but we can fix that with script as well, what skin do you use?

Posted Mon 02 Jul 18 @ 4:04 am
locodogPRO InfinityModeratorMember since 2013
Had a quick tidy up of a few posts, I think the next one will be the dark art of param_cast, param_multiply, param_add and how to do something useful with them.

It'll take a while to write up and I'll help supertess in between, and anyone else who has an idea or wants a concept explaining.
BUT don't go empty handed, here's a script I wish I had known about a long time ago (would have saved me many thousand mouse miles during mapping)

settings "controllers"

stick that on a keyboard button, and save yourself a few seconds for every mapping you do. ;-)

Posted Tue 03 Jul 18 @ 2:02 am
locodog wrote :
[quote= ]

Now you have control but no visual feedback, but we can fix that with script as well, what skin do you use?

Thanks so much for that help. Away from my laptop at the moment but will try it out as soon as I get back home and let you know how it went. I use the silver sleek 3 skin

Posted Thu 05 Jul 18 @ 10:37 pm
locodogPRO InfinityModeratorMember since 2013
Silversleak3, too many changes needed to work out as a tut, I'll give you the basics.

Posted Fri 06 Jul 18 @ 11:19 am
I put up a simple page to format VDJ script. It can take normal VDJ script and format it into something more readable. It can take formatted script and convert it back to non-formatted. The formatted script can be pasted into a local editor (without the color coding), edited, and then converted back to non-formatted script. It can also format the script into BB Code so it can be displayed with color coding and proper alignment here in the forums. The only thing with BB Code is it will wrap if the lines are too long since the [pre] tag does not work. I have a partial solution but not complete. I also had to put dots in the BB Code version since spaces will collapse but should be invisible since I colored them the color of the [.code.] page. But you can paste non-formatted script, formatted script, or BB Code formatted script dots and all into the webpage and it will convert between them. At the webpage, the enhanced formatted script will show without the dots or wrapping. All of them can be pasted into a local editor or here. Only the BB Code formatting will show as color coded and aligned when displayed here in the forums though.

This formatting makes script easier to deal with and brings up questions and also can create some interesting patterns.

Here's a simple example:

normal non-formatted script

var 'double' ? set 'double' 0 & repeat_stop 'myrep' & device_side 'left' ? deck left clone_deck right : deck right clone_deck left : set 'double' 1 & repeat_start 'myrep' 400ms 1 & load & set 'double' 0

same script formatted as BB Code

var 'double'
..? set 'double' 0 & repeat_stop 'myrep' & device_side 'left'
....? deck left clone_deck right
....: deck right clone_deck left
..: set 'double' 1 & repeat_start 'myrep' 400ms 1 & load & set 'double' 0

VDJ script keywords are colored blue. If a keyword is expected and maybe it is misspelled or not yet recognized then it will be colored red. In the following I misspelled repeat_stop as repet_stop:

var 'double'
..? set 'double' 0 & repet_stop 'myrep' & device_side 'left'
....? deck left clone_deck right
....: deck right clone_deck left
..: set 'double' 1 & repeat_start 'myrep' 400ms 1 & load & set 'double' 0

If there is interest I will improve it.

You can try it here:

I tested it in Firefox, Chrome, and Internet Explorer. IE will ask if it is ok if the page copies to your clipboard one time but the others won't. When you have pasted in some script and click any of the buttons, the result is automatically copied to the clipboard which makes it available to paste elsewhere.

Posted Sat 14 Jul 18 @ 1:16 am
locodogPRO InfinityModeratorMember since 2013
Interesting Don,
I'll try use it as often as possible on the forum.
I work with logic trees like this myself and use np++ to remove indents and join lines.
I imagine that the hardware mapping team would have something similar to your page.

Posted Sat 14 Jul 18 @ 12:58 pm
Just the basic of a tool for anyone doing any kind of coding. In a typical programming environment there is much more like the ability to trace thru execution and error trapping.

When I did this, the first thing I did was to copy all the text from the 2 verb pages associated with VDJ script. Using this text, I wrote a little bit of C++ code to parse thru it and extract keywords. It also tried to determine which ones were queries and which ones were not. It also determined which ones were DEPRECATED. So it has the ability to do more. The thing with VDJ script is you have a mix of queries and non-queries in a single, what is supposed to be a boolean, statement of sorts. Your typical beginner is not going to know the deference since it looks exactly the same in the script. Only the first query is relevant for the boolean test unless separated by && which you already mentioned. All these things can be identified as well to make the syntax checking better. I have no idea what the result of a non-query keyword is in a statement so I have to assume it is undefined as far as the boolean test goes. The doc says some keywords return results which implies some do not. This is a list of keywords that the parsing code came up with for actual queries. This was done by the parsing code examining the comments next to the keywords so it is probably not complete. I don't know how a human is supposed to determine some of it without some guessing or without some experience.

This is just a list of keywords that are supposed to be queries and not the entire list of keywords and not the entire list of queries it appears either. An attempt was made to determine if some keyword was a query by an automated process. I assume there are more queries but from the doc the code did not figure it out.


Posted Sat 14 Jul 18 @ 4:11 pm
Also if you do paste the enhanced formatted script into some text editor, be sure you are using a mono-spaced font like Courier. This means every character in the font has the same width. This ensures that lines of text will align properly and is standard practice in most coding environments.

Posted Sat 14 Jul 18 @ 5:01 pm
locodogPRO InfinityModeratorMember since 2013
Don Moir wrote :
I don't know how a human is supposed to determine some of it without some guessing or without some experience.

True, there are some verbs what do have their own rules, and yeah some of my best scripts were a trial and error & error & error, my next lesson is aimed at removing some of the guess work from some of the param_ verbs, every language has it's own quirks, vdj script is no different.

All said, a good idea Don, whatever the forum code language, indents would be useful.

Posted Sat 14 Jul 18 @ 7:01 pm
I assumed that the execution of a non-query keyword would return false. That was expected, but in the following, set 'var1' 1 is not executed which was not expected. set 'var3' 3 is executed though.

set 'var1' 1 ? set 'var2' 2 : set 'var3' 3

In order to get set 'var1' 1 to execute you need to do:

set 'var1' 1 & false ? set 'var2' 2 : set 'var3' 3
set 'var1' 1 & true ? set 'var2' 2 : set 'var3' 3
set 'var1' 1

I thought that was strange. In the above posts, I was implying that it is important to know what verbs are queries and what ones are not. Probably fairly easy to make a mistake with that and then you have some odd behavior to boot. The documentation tells you above some queries, but not for others so it leaves you guessing.

As a side note, I was playing with the script engine from C++ and was tracing thru it some and noticed that newlines are ok when sent from C++. But when newlines are used in the script text on a skin, they do not appear to work so I assume that when the text sent from the skin, the text is truncated at the newline. It is still there for display though.

Adion wrote :
In the first one, you are querying set instead of executing it. In that case it's similar to checking the value of 'var1' and comparing it to 1.

In the second and third one, it should be read as
set 'var1' 1 & (false ? set 'var2' 2 : set 'var3' 3)
Which you could more simply just write as
set 'var1' 1 & set 'var3' 3

(Regardless, if you would expect the first one to set var1, I'm not sure what you would expect the question mark to do in that case, since the var would always be set to what you asked it to be set to)

Edit: The reason why set also works as a query is so that it would also work on buttons for example without having to write a separate query for lighting up the button.

Don Moir wrote :
Ok that explains that then but then you can see the confusion of it I think. So is it such that everything can be treated as a query?

in C++, I might do something like:

int var1;
int var2 = 2;
if (var1 = var2) // assignment and test something;

locodog wrote :
New lines and indents are fine in pad/mappers editor. Have been for at least 6 months probably longer.

Don Moir wrote :
Well I put a newline into Phatoms collapse script on one of the custom pad buttons and it no longer worked. The same script with the newlines did work when sent from C++ so go figure. Extraneous spaces have always worked I believe.

edit: Ah I see, it depends on where you put the newline. If before a ? then it appears not to work. If after the ? then it works. So inconsistency?

So I double checked, and the script that did not work with just one newline from the skin, does work when sent form C++. Originally I sent the complex script with a newline before every ? and : and that also worked when sent from C++.. But that script also does not work when put on a skin button.

Don Moir wrote :

Adion wrote :
Edit: The reason why set also works as a query is so that it would also work on buttons for example without having to write a separate query for lighting up the button.

When I was first testing this, I was using effect_string instead of set. Since it was my effect_string declare, I expected it to fire my code but it does not. No telling what the query value of it is except false.

edit: Some of these things just come up when I am testing for doing other things. When I tested newlines in script long ago, it did not work. But when I am tracing thru the SendCommand last night, I see that newlines are handled. So I try that in C++ and it worked. Thought to try it from a skin button and ran into problems. Same sort of thing with queries but in that case also a user needs consistency. For my goal it is something different, but still, I or we need to know :)

Adion wrote :
When queried, 'effect_string 1 "test"' should be true if the string is equal to "test"

Don Moir wrote :
Ok... since the declares don't have an option to handle queries, I guess that makes sense. In the doc it says:

Commands can be used either as actions or as queries, depending on the context.

Some commands can return a boolean (true or false) or a value, depending on the parameters:
- "crossfader" will return the value (between 0.0 and 1.0) if used in a query. Will also return true if its value is greater than 0.5 and false if smaller.
- "crossfader 42%" will return true if the crossfader is at 42%, and false otherwise.
Some other commands can return a string or a number, depending on the verb. (usually verbs starting with get_ )
- "get_time_ms" will return the time of the loaded track in ms as an integer
- "get_artist" will return the Artist of the loaded track as text

...and some other commands do something else I guess.

That seems to say every keyword can be a query or an action and it just depends on the keyword as to what the query result (and parameter) actually is. Maybe every keyword should be documented as to what the query of it means. I am not sure what the query value of get_ms would be for example but from your explanation it might be get_ms '1000' and then be true if equal to '1000'. Useless test I know but just for clarification.

If I use something starting with get_ it may not mean get and it might mean just test the value of whatever.

Adion wrote :
typically the boolean query 'action value' is only implemented if that is also a valid action for setting something to that value, for the reason mentioned above.
get_time_ms can not be used as an action to set the time, so it only returns the time as advertised.
For queries involving these, you can of course use param_equal etc... to compare them and use them in boolean queries.

Don Moir wrote :
Thanks. so get_effect_string when used as query does not get the effect string... gotcha :) and is actually implemented as test_effect_string

Adion wrote :
Typically, you use get_effect_string to get the actual string value, which it will of course do, and not to check if it has a specific value.
effect_string on the other hand would be used to set the string to a specific value "effect_string value", and can therefore also be used in a query to check for this specific value.

In this specific case, get_effect_string is just a synonym for effect_string, so both will actually work. get_ for many actions is only there because of compatibility with v7.
For new actions that make sense both as get_ and set_ just a single one will usually be added to do both query and set.

Don Moir wrote :
Yeah I saw that get_effect_string is just a synonym for effect_string and realizing now why you are probably wanting to get rid of the get. You know that in normal programming things tend not to be seen as ambiguous and in general considered to be bad. Meaning in most languages, if you call a function, no matter how it is used in a statement, the function is called.

I realize you are trying to keep script simple, but simple only works to a point before the simple becomes complex. I have been thru this before with much discussion in another world. Feeling like we are getting off subject in loco's thread to a degree now though. Thanks for the info guys.

Posted Sun 15 Jul 18 @ 5:18 pm
locodogPRO InfinityModeratorMember since 2013
Param_cast, param_add, param_multipy, lots of param stuff.

Now as of EA4490 as far as I can see, basic arithmetic is possible in script so....

Guess what we're going to do? We're going to build a calculator (...sort of) with a pad page.
So what use is it for performance? None (I suppose you could work out if you've been ripped off at the bar......I'll save you the effort, you have.), BUT if you have it as a padpage you can reference it when you need to.
just have it there make it an hidden padpage so it stays out of your way (like sticking a textbook in the loft/attic, there when you need it)
That and pad pages are just so useful, as a test ground of scripts, to show you info, (might do a whole lesson on this... maybe rsi)

Start off a couple of scripts to save a second or two many times for years to come

deck 1 pad_edit
deck 2 pad_edit
stick these on a couple of keyboard buttons, it really saves time in the future.

Here we start, press deck 1 pad_edit button, up pops the editor (hello padpage!) click new pad page and call it calculator.

on pad 1 put this script
set 'var1' 8 && set 'var2' 2

name this button "Set"
we're just setting var1 to 8 and var2 to 2, (the && is so the pad only lights if both are set, not important)

on pad 2 put this script
get_var 'var1' & param_bigger "get_var 'var2'" ? on : off press enter, add a space on the new line and add this memory aid in quotes
"is the first thing bigger than the second ? yes lights on"
could use && here to avoid ? on : off , but didn't

(at the end of scripts you can put stuff in quotes AFTER A SPACE and vdj ignores it)
Name this button "compare 1"

ok close the editor and press button 1, button 5 lights up, var1 is indeed bigger than var2

back into you editor
on pad 3 put this script
param_bigger "get_var 'var1'" "get_var 'var2'" ? on : off (and enter newline space, your memory aid)
"is the 2nd thing bigger than the first? if yes lights on"
call this "compare 2"

wait this looks backwards.... yeah it does, remember the lesson back when I said the implicit is stuck on the end of a script? (you don't?! have a reread of lesson 6 how vdj gets values) well this is what vdj sees when you press button 2
(atomix made it this way so the; value, compare, value order (like button 2) looks right to our monkey brains. If button 3 was the way we'd expect, then button 2 would be backwards, no ways around it)

Now finally for compare button 4, here's the script
get_var 'var1' & param_equal "get_var 'var2'
call this "equal"

There is another way this can be written (param_equal "`get_var 'var1'`" "`get_var 'var2'`") this way you need backticks more on that later, I think this is because param_equal can be used to compare an action to a string (string being a collection of letters,numbers,chars) so vdj needs to know, is it a script or is it a string.

ok back to pad 1 and change the values for the vars, no matter what you put, when you click button 1 one of pads 2,3 or 4 will light up, it has to be v1 bigger than v2, v2 bigger than v1, or v1&2 equal

compares done now some arithmetic
but first let's display what's going on, open the editor, go to param 1 script box, press space (a bit of weirdness explain later) for the param 1 name put
var1 = `get_var 'var1'` var2 = `get_var 'var2'`

UH ok what's going on here, remember this is a textbox not a script box, so it will display
var1 =
then the backticks ( ` this little fella,) tells the textbox "this next bit is script, read it as a script" the second back tick says we're back on letters now, and so on.

so close the editor again as param 1 you'll see
var1 = # var2 = # (I put # as I've no idea what values you've given to the vars by now)

Now the second bit of the display the total
back into the editor, param 2 a quick space in the script box (param1&2 labels don't show unless there's something, anything in the script box)
and put this as param 2's name
var3 = `get_var 'var3'`
like above, but var3 will be our answer.

ok maths (it has a s on the end, it's plural, live with it)
button 5 call this one "add", here's the script.
param_add "get_var 'var1'" "get_var 'var2'" & param_cast & set 'var3'

Ok what's happening here, param_add easy enough, why the quotes round get_var 'var1' .....? well param_add expects a number or a script but if the script contains a space it confuses the verb so wrapping in quotes tells it "inside here is one script action", same again for get_var 'var2', ok so it's done the maths we save the value by, casting, (param_cast) this tells vdj to take the last value it had and stick it on the end on the next script, (like the implicit)
and here we cast to the end of " set 'var3' "
close the editor and have a try.

button 6 call this one multiply
param_multiply "get_var 'var1'" "get_var 'var2'" & param_cast & set 'var3'

straight forward, like before

ok things get a bit mathematical now as vdj doesn't have a param_divide or a param_subtract

button 7 call this one subtract
get_var 'var1' & param_invert & param_cast & set '1-var1' & param_add "get_var '1-var1'" -1 & param_cast & set '-var1' & param_add "get_var '-var1'" "get_var 'var2'" & param_cast & set 'var3'
memory aid
"((1 - var1 = 1-var1) -1 = -var1) + var2 = var3" "var2 - var1"
so we get var1 and invert it (vdj's invert is made for sliders so it uses 1-X, real inversion would be X - (2X), Lets say var1 = 7, so the inversion 1 - 7 = -6, we cast that to a new var '1-var1' & then param_add '1-var1' to -1 now we cast that to another new var '-var1' and it's a true inversion of var1, fantastic now we add -var1 to var2 and cast that to var 3 for our result.

finally button 8 call this one divide
get_var 'var1' & param_1_x & set "1/var1" & param_multiply "get_var '1/var1'" "get_var 'var2'" & param_cast & set 'var3'
memory aid
"(1/var1) * var2" "=" "var2 / var1"

ok no divide script but 8/4 is the same as 8 * (1 / 4) and vdj does have a 1/x script, so we use it, we've broken from form here, we haven't cast to the set '1/var1'
this is just a quirk of the 1_x script it expects to be cast and adding cast just after it makes vdj confused, (found that out the hard way...) the rest is just a multiply & set.

I'll level with you here, there's a few places in all these button scripts where param_cast is not needed, but I wanted the lesson to be consistent and they do no harm,
but the 1/x script it does harm and (there goes my consistency) has to be omitted.

ok that's that, have a quick play to make sure it works and then make the padpage hidden.
Next we'll try something useful with these concepts.
(some of this stuff above is really new, the verbs have been around for time but being able to do this type of thing has only just become possible)

I recommend you have a poke around at making a padpage there's a bit more to a finished padpage than described here... but not much more.
But in true Blue Peter style, here's one I made earlier (new text file, copy and paste) save as "mathsRef.xml" and pop it in your pads folder.

And for no reason I put some more stuff on shiftpads (NaN fans try shiftpad 6 for Sqrt of -1)

Posted Tue 17 Jul 18 @ 3:03 pm
locodogPRO InfinityModeratorMember since 2013
Everyone hates edits populating their what's new feed, I've just updated the last post with a link to the calculator in xml ready text.

Posted Tue 17 Jul 18 @ 8:10 pm
Just want to say BIG Thanks mate ;o)

Posted Tue 17 Jul 18 @ 8:21 pm
locodogPRO InfinityModeratorMember since 2013
No worries, a proper way to do maths, how could I not share it?

Posted Tue 17 Jul 18 @ 8:27 pm
locodogPRO InfinityModeratorMember since 2013
So I've not got round to another topic yet but here's one I just helped a guy with over on FB

Wedding entrances, a right old pain, you've a mic and notes and you've got a list of short tracks to play and you don't have time to drag the next one to deck.
You want the automagical powers of the rsi (repeat_start_instant) script, I want to go quite a way with rsi scripts but this is a nice start

Set your playlist in the side list

put this on a custom button
deck 1 var 'autoloadsys' 1 ? on & deck 1 set 'autoloadsys' 0 & repeat_stop 'RSIautoload' & set 'played' 0 : off & deck 1 set 'autoloadsys' 1 & browser_window 'sidelist' & browser_scroll 'top' & sidelist_load_and_remove & deck 1 repeat_start_instant 'RSIautoload' 50ms & deck 1 play ? set 'played' 1 : var 'played' ? deck 1 unload & sidelist_load_and_remove & set 'played' 0 : nothing

press the custom

it will jump the browser scroll to the top of the side list and load to deck then remove the track from the list.
it then waits for you to press play, when you press play it sets a var 'played' to 1, it then waits and watches for the deck till it's not playing (either by ending or you pressing pause) when not playing it unloads the deck, sets 'played' back to zero and then sidelist_load_and_remove the next in the sidelist.

here's the breakdown

deck 1 var 'autoloadsys' 1 ? on & deck 1 set 'autoloadsys' 0 & repeat_stop 'RSIautoload' & set 'played' 0 :

var autoloadsys is true when this thing is running, is the var = 1 ? yes, on is for the button light, so we're running turn the var to zero and stop the rsi script (that I called RSIautoload) also set the var 'played' to zero (good housekeeping)

off & deck 1 set 'autoloadsys' 1 & browser_window 'sidelist' & browser_scroll 'top' & sidelist_load_and_remove &

var autoloadsys if false, we're not running : off is for the light, set the autoloadsys var to 1, jump to the sidelist, jump to the top load track to deck and remove from list

deck 1 repeat_start_instant 'RSIautoload' 50ms & deck 1 play ? set 'played' 1 : var 'played' ? deck 1 unload & sidelist_load_and_remove & set 'played' 0 : nothing

here's the magic, I set up the rsi I give it a name "RSIautoload", I give it a repeat time 50ms, I Then give it a command to repeat.
Is deck 1 playing ? yes set 'played' to 1 : no not playing, is var 'played' true ? yes unload, load track, remove from playlist, reset the var 'played' to zero : not playing and var played is false, then we're waiting for the next track to be played, do nothing

To be proper pro about it, you'd have a mic stand and a foot switch to act as a play button

deck 1 var 'autoloadsys' 1
..? on & deck 1 set 'autoloadsys' 0 & repeat_stop 'RSIautoload' & set 'played' 0
..: off & deck 1 set 'autoloadsys' 1 & browser_window 'sidelist' & browser_scroll 'top' & sidelist_load_and_remove & deck 1 repeat_start_instant 'RSIautoload' 50ms & deck 1 play
....? set 'played' 1
....: var 'played'
......? deck 1 unload & sidelist_load_and_remove & set 'played' 0
......: nothing

Posted Sun 29 Jul 18 @ 7:07 am
A quick question I got on FB

"How do I change the LED color based on the camelot key"

I thought it would be something like:
param_equal '`get_harmonic`' '01A' ? <change the led color>
- but that doesn't seem to work

Then if param_equel accepts an action by default it could be as simple as:
param_equal get_harmonic '01A' ? <change the led color>
- but that doesn't seem to work either

What am I missing?

Posted Thu 13 Sep 18 @ 2:29 pm
AdionPRO InfinityCTOMember since 2006
param_equal '`get_harmonic`' '08A'
seems to work fine for me, it's true when the key is 08A, and false otherwise.

Posted Thu 13 Sep 18 @ 3:16 pm
Adion wrote :
param_equal '`get_harmonic`' '08A'
seems to work fine for me, it's true when the key is 08A, and false otherwise.

Then I messed up the easy part somehow :-D
Sorry - my bad

Posted Thu 13 Sep 18 @ 5:09 pm