4 separate on/off switches on same parameter address?

Home Forums General Programming 4 separate on/off switches on same parameter address?

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • #71048
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • ★★★★

    quizz time?
    Roland D110 manual:
    http://cdn.roland.com/assets/media/pdf/D-110_OM.pdf
    (p118/119)
    i’m looking for ideas on how to create 4 separate on/off switches
    for the partials. these are all at the same address (on the same
    parameter) with a 0-15 data range, representing all possible combinations.

    the sysex message is:
    F0 41 10 16 12 04 00 0C DV cs F7
    (OC is the parameter number, DV is the variable, cs is the checksum)

    to switch on partial#1 only, the value is 1. but 0 is all partials off.
    partial#2 is 2, partial#3 is 4, partial#4 is 8.

    in binary:
    0001
    0010
    0100
    1000

    but it needs to be able to select all partial combinations as
    well, and uses 0-15 to get these.

    these are 4 Partial Mute buttons, and there are 16 possible
    combinations, 0-15/00h-0Fh/0000-1111

    the bits used are:
    0000 aaaa ( maybe that should be 0000 abcd, or rather 0000 dcba
    -since rightmost is partial#1, it goes right to left.

    see below>

    • This topic was modified 5 years, 3 months ago by human fly.
    • This topic was modified 5 years, 3 months ago by human fly. Reason: brevity
    #71210
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • ★★★★

    ok, i think i have some clues:

    i saw something like this:
    if P1 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x01, 0x00, 0xf7})) end

    i think this means that if the button called P1 has value 1, it will send the
    sysex message shown (the checksum byte is incorrect, i didn’t calculate it yet)

    but i have to take into account the state of all 4 buttons, and the 16 possible
    combinations of the 4 buttons, to send the correct value to their shared parameter. so i think i want to have 4 ‘if’s/conditions, so something like
    this:

    if P1 == 0 + P2 == 0 + P3 == 0 + P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x00, 0x00, 0xf7})) end

    except that + is probably wrong, i can’t find how to combine conditions,
    would it be? :
    if P1 == 0 (needs ‘and’ or something here?)
    if P2 == 0
    if P3 == 0
    if P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x00, 0x00, 0xf7})) end

    if i can get thse 4 ‘if’ combined, and get the rest of the syntax right,
    and have an expression for each of the 16 states of the 4 buttons,
    i’m hopeful it could work (…)

    • This reply was modified 5 years, 3 months ago by human fly.
    #71214
    computerchemist
    Participant
    • Topics: 2
    • Replies: 31
    • Total: 33

    You need bitwise operators to solve this. I haven’t tried yet, but for example 4 (0x0100) and 2 (0x0010) like this 4 & 2 would give 6 (0x0110) which would be adding the two together, whereas 6 or’d with 2 (0x0110 | 0x0010) would give 4 (0x0100).
    Does that make sense? So the first variable would be the current switch state, the second would be the switch to change (always 1,2,4,8,16,32,64,128) which would represent the 8 bits.

    #71218
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • ★★★★

    i quite like my solution if i can have multiple ifs.
    it isn’t a problem to have all the 16 options listed in that case
    in the expression. i don’t know how it works.

    it only uses the first 4 bits.
    wouldn’t if+if+if+if be AND’ing ?

    yes, my first thought was to have a series of logic gates,
    but i want to ditch that idea if i can and keep it simple.
    like this:
    here are the options: (oh, the alignment is all wrong, sorry)
    —————————————————
    0000 ALL OFF /0
    0001 1 /1 partial1 solo
    0010 2 /2 partial2 solo
    0011 1+2 /3
    0100 3 /4 partial3 solo
    0101 3+1 /5
    0110 3+2 /6
    0111 2+3+4 /7
    1000 4 /8 partial4 solo
    1001 4+1 /9
    1010 4+2 /10
    1011 4+2+1 /11
    1100 4+3 /12
    1101 4+3+1 /13
    1110 4+3+2 /14
    1111 4+3+2+1 /15
    ————————————————–
    and this is what i thought of (derived from the D50 panel):
    i know the + sign is not valid, i want to know what i should use.
    ————————————————–
    if P1 == 0 + P2 == 0 + P3 == 0 + P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x00, 0x00, 0xf7})) end

    if P1 == 1 + P2 == 0 + P3 == 0 + P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x01, 0x00, 0xf7})) end

    if P1 == 0 + P2 == 1 + P3 == 0 + P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x02, 0x00, 0xf7})) end

    if P1 == 1 + P2 == 1 + P3 == 0 + P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x03, 0x00, 0xf7})) end

    if P1 == 0 + P2 == 0 + P3 == 1 + P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x04, 0x00, 0xf7})) end

    if P1 == 1 + P2 == 0 + P3 == 1 + P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x05, 0x00, 0xf7})) end

    if P1 == 0 + P2 == 1 + P3 == 1 + P4 == 0 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x06, 0x00, 0xf7})) end

    if P1 == 0 + P2 == 1 + P3 == 1 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x07, 0x00, 0xf7})) end

    if P1 == 0 + P2 == 0 + P3 == 0 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x08, 0x00, 0xf7})) end

    if P1 == 1 + P2 == 0 + P3 == 0 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x09, 0x00, 0xf7})) end

    if P1 == 0 + P2 == 1 + P3 == 0 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x0a, 0x00, 0xf7})) end

    if P1 == 1 + P2 == 1 + P3 == 0 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x0b, 0x00, 0xf7})) end

    if P1 == 0 + P2 == 0 + P3 == 1 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x0c, 0x00, 0xf7})) end

    if P1 == 1 + P2 == 0 + P3 == 1 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x0d, 0x00, 0xf7})) end

    if P1 == 0 + P2 == 1 + P3 == 1 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x0e, 0x00, 0xf7})) end

    if P1 == 1 + P2 == 1 + P3 == 1 + P4 == 1 then
    panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, 0x0f, 0x00, 0xf7})) end

    • This reply was modified 5 years, 3 months ago by human fly.
    • This reply was modified 5 years, 3 months ago by human fly.
    #73000
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • ★★

    Hi there Human Fly!

    I would create an array of the buttons, then multiply by 1,2,4, or 8 through a loop adding each button state on/off. They will add up to anything from 0-15. Then just send that value in the sysex.

    fourButtons = function(--[[ CtrlrModulator --]] mod, --[[ number --]] value, --[[ number --]] source)
        a={"P1","P2","P3","P4"} --array of buttons
        m={1,2,4,8} -- multiplier
        sumOfa=0 --variable to hold multiplied values
        for i,v in ipairs(a) do
            local val=panel:getModulatorByName(v):getModulatorValue()
            sumOfa=sumOfa+val*m[ i ]
            --add up the values 
        end --loop
        console(String(sumOfa))
        --You then don't even need to do an if // else - just include the sum in the sysex message
        cs=myCheckSumFunction(0x12, 0x04, 0x00, 0x0c, sumOfa)
        panel:sendMidiMessageNow(CtrlrMidiMessage({0xf0, 0x41, 0x10, 0x16, 0x12, 0x04, 0x00, 0x0c, sumOfa , cs , 0xf7}))
    end --function
    ---------------------------------------------------------
    myCheckSumFunction=function(...)
        local total=0
        local result=0
        for i,v in ipairs(arg) do
            total=total+v --addup all the numbers
            if(total > 127) then
                total=total - 128
            end
        end
    
        result=128-total
    if result== 128 then result = 0 end -- If the result is 128 then substitute a value of 0
        return result
    
    end --function
    ---------------------------------------------------------

    NOTE: the attached panel has a small error “return result,10” in myCheckSumFunction() (but still works – should be just “return result”

    Attachments:
    You must be logged in to view attached files.
    #73001
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • ★★★★

    (irish accent) oh bejazuss, oi’ve been sitting here all this time..
    (not really, i hacked onwards..)
    🙂
    thanks for the suggestion! i’m going to try this out.

    cs=myChecksumFunction(sumOfa) ?

    • This reply was modified 4 years, 8 months ago by human fly.
    #73012
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • ★★

    Hi Human Fly – I realised it was an old post, but I thought just in case you were wilting away all this time 🙂

    Well, the
    cs=myChecksumFunction(sumOfa) is (pseudo) code for calculating the checksum. The function myChecksumFunction(sumOfa) would actually look ‘something’ like:
    myChecksumFunction(0x12, 0x04, 0x00, 0x0c, sumOfa)

    myChecksumFunction=function(...)
        local total=0
        local result=0
        for i,v in ipairs(arg) do
            total=total+v --addup all the numbers
            if(total > 127) then
                total=total - 128
            end
        end
        result=128-total
    	if result== 128 then result = 0 end -- If the result is 128 then substitute a value of 0
        return result
    end --function
    ---------------------------------------------------------
    • This reply was modified 4 years, 4 months ago by dnaldoog. Reason: minor correction if result == 128
    #73015
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • ★★★★

    very nice. i’ll have that, if i may 🙂

    i think i was shown something similar previously but was
    probably not able to take it in at the time.

    what i have difficulty with currently (among other things)
    is loops, and the form

    for i,v in ipairs(arg) do...

    i think (arg) is any variable you want? i’m no good at
    defining variables, ‘up top’, next to the function name,
    either.

    reason why > i would have liked to have been able to apply
    web tutorial examples within Ctrlr – for a bit of ‘practical’:
    that’s how i learn, and commit stuff to memory. i need to have
    a go at that again.

    #73023
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • ★★

    Hi Human Fly – arg must be an array or table as it is (usually?) called in Lua. An array is a set of usually related items collected together so you can loop through them.
    for i,v in ipairs(arg) do...
    will then loop through the array – i is the position in the array (a counter) starting at 1 and v is the value for that position. Obviously very useful if you have a large number of items to process.

    For example on page 117 of the Roland D110 manual you could have a lua array of all the parameters in 5-1-2 starting with WG Pitch Coarse as the first item in your table and the last (58th 0x3A -> 0-57) item TVA Env Sustain level. The D110 address of each parameter would be i-1 (the Roland will start at 0, not 1)

    arrayOfParams={"WG Pitch Coarse",..[insert 56 items here]....,"TVA Env Sustain level"}
    for i,v in ipairs(arrayOfParams)do
    console(String("address is: "..string.format("%0.2x",i-1)..": name is "..v))
    end
    #73024
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • ★★★★

    AHA someone talking to me about page 117 (and 118) of the D-110 manual !
    now that’s promising 🙂

    i apologise for my laziness in asking that question – when i looked at
    this briefly the other day, that revelation came to me, whereas i was
    eye-skimming over those ‘forms’ before, and have not got round to
    handling a few examples myself (because i hack on with the other stuff,
    by default, as i find it easier to get my head round. especially when
    real life issues might not allow taking the day off to do this atm)

    so: yes, at some point, all parameters must become a table of some kind.
    i have some beginning of that, and can initialize a default patch at the
    moment, and have an ‘init views’ method as well, in my startup.

    still sketching out layout – Timbre, this morning, as i need a Timbre
    List (that will need to be recalled and updated to show what Tone each
    Timbre contains), and the parameter display, which must be on a 8x tab,
    if this is going to be a multitimbral editor(…lots of parameters…
    makes you realise that the processor in the D-110 can’t be too bad if
    the thing starts up faster than a Ctrlr panel loads ! and that the
    Roland programmers did a thorough job, with some nice little touches,
    even if everyone ended up moaning about the interface).

    #73060
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • ★★★★

    “in ipairs”

    ok, i now know what this means: item and value pairings.

    is this a term unique to Lua, or is it a more widely
    used programming thing? just my need to know where
    this ‘ipairs’ originated from – because i’ve had a
    kind of blockage each time i’ve seen it 🙂

    #73081
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • ★★

    I think the ‘ipairs’ or ‘pairs’ must be unique to lua, but it is central to any programming language (looping through an array’s index and value), so the syntax will vary from language to language, for example php uses foreach (i as v){} – but if you get into lua you will need to be familiar with ipairs and pairs (there is a difference).

    Regards

    #73083
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • ★★★★

    thanks. so what is ‘pairs’ for ?
    there, i think i’ve ‘got’/assimilated ipairs now 🙂

Viewing 13 posts - 1 through 13 (of 13 total)
  • The forum ‘Programming’ is closed to new topics and replies.
There is currently 0 users and 51 guests online
No users are currently active
Forum Statistics
Threads: 2,495, Posts: 17,374, Members: 77,605
Most users ever online was 12 on January 22, 2019 3:47 pm
Ctrlr