Demo panel for MIDI receive/transmit routines

Home Forums General Using Ctrlr Demo panel for MIDI receive/transmit routines

Viewing 20 posts - 41 through 60 (of 71 total)
  • Author
    Posts
  • #73279
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • β˜…β˜…
    myMethod = function(--[[ CtrlrModulator --]] mod, --[[ number --]] value, --[[ number --]] source)
    	extBank = L(panel:getModulatorByName("lcd_bankDataB"):getComponent():getProperty("uiLabelText"))
    	console("Retrieving external bank : "..extBank)
    
    --make a memory block from the string
    	memB = MemoryBlock(extBank) -- this variable is used to send midi????
    
    --check size of received dump
    	local size = memB:getSize() -- same as size=string.len(extBank)???
        console("midiMessageReceived: " .. size .. "bytes")
    
    		if size == 80 then 	--bank dump
    		console("bank dump detected!")
    		end
    extBank:gsub("(%w+)",function(c) table.insert(tabl_extBank,c) end)
    for i,v in ipairs(tabl_extBank) do
    console("i="..i.." v="..v)
    end
    console("size of tabl_extBank="..#tabl_extBank)
    end

    –convert bank to table tabl_extBank = {} for i=1,80 do s=extBank:toHexString(1) table.insert(tabl_extBank,s) end

    I think toHexString(1) just dumps a memory block into a string. ‘extBank’ is a string obtained from a uiTextLabel, so it is not a memory block. To convert a string into a table, you would need to split or explode it somehow using a delimiter (like excel does with csv files). The code above gsub(“(%w+)” does a similar thing by ignoring whitespace and just loading the number 0-9 or letter A-F into each element of the table. Not fully tested though πŸ™‚

    extBank:gsub("(%w+)",function(c) table.insert(tabl_extBank,c) end)
    I found it here.

    #73281
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    scary. going to have to get my head round that.

    quick recap: i put extBank into memory block memB just so that
    i could getSize() on it without it returning a nil error.
    trying to (ermm) keep it as similar as possible to what happens
    when it’s a Ctrlr midi message. as in (midiMessage).

    i’m thinking that if i can get all the bytes of the big string
    into a table, then it will be easier to get them by index with
    getRange() – which has been returning nil errors as well – and
    then i can do what i want with them (within the limited capabilities
    at my current disposal lol). i’m very heath-robinson/string+sellotape.

    but this is what happens, isn’t it, when a bulk dump comes in, and
    the device, or panel, want to send its little presets into their
    little pigeonhole memory slots, and then everyone’s happy. right?

    hello device, send me your stuff. ok, here it is, do your thing.
    ok, thanks. this goes here, this goes here…etc…and this one
    goes here, done.

    mainly called ‘midiMessageReceived’ in most of these panels i look
    at. edit: no it, isn’t, i just looked; i can’t remember where i’ve
    seen the thing i remember.

    say, if i had a sysex header in there: ‘f0 41 10 blabla’ and f7 at
    the end, on the bulkdata – then i’d want to skip the header and
    ender, but all would have an index position, say, in a table(i like
    array, that’s cool too – seems people talk about tables here), so
    i just want to grab index ranges and send the data to the preset
    slots. i think that would do it.

    (believe it or not, i was trying/achieving text based sequencers
    in synthedit with similar techniques – sirsicksik/siksick was the
    master of this, but nobody ever understood his prefabs. or his
    plugins…)

    can we skip gsub for the time being? πŸ˜€

    #73283
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • β˜…β˜…

    Well I never looked at the reason for this function, just focusing on the errors you were dealing with and offering a way of fixing those (particular issues), but it seems that all you are trying to do is process the data coming in from the synth.

    I don’t think you need to do all that memoryblock converting or midi:getLuaData():getRange(), gsub() stuff. Needs to be as simple as possible or else all these compilation errors start seeping in as you are finding out.

    If you know a certain midi dump will be say 65 bytes long then:

    myMidiReceived = function(--[[ CtrlrMidiMessage --]] midi)
        local s = midi:getSize()
     if s == 65 then

    …now work out a way of writing into the values of a midi:getLuaData():getByte() to various modulator/components (uiSliders uiCombos etc); that magic moment when you see all the sliders change values on screen!

    You can do this by mapping the position of each byte in midi:getLuaData():getByte() to a table of modulator/Component names.

    This would be the foundation/core of your whole program!!! Everything else should be designed around this central function of Ctrlr πŸ™‚

    e.g.

    
    t={
    "WG_PITCH_COARSE", --  0x00 this would be the name of the Modulator/Component
    "WG_PITCH_FINE", -- 0x01
    "any_mod_name_I_choose", -- 0x10
    -- <em>54 more elements to be listed here</em>
    "TV_ENV_SUSTAIN_LEVEL”, -- 0x39 
    }
    --pseudo code follows untested!!
    j=1
    for i=5,65-2 do
    --  5 could be the offset from the sysex header F0 41 ?? ?? ??
    -- -2 = ignore checksum and F7 (in the case of Roland Synths)
    m=midi:getLuaData():getByte(i)
    panel:getModulatorByName(t[j]):getComponent():setValue(m,false)
    j=j+1
    end
    

    This is all untested, but hopefully it will help you understand the core idea of getting data out of the D-110 and into ctrlr. πŸ™‚

    #73284
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    ok, i see how that last section works – this is ok as long as
    all values incoming are ‘literal’, and i don’t have to deal
    with any ‘mapped’ offsets ie: pan with midi value 0-14 where it
    is displayed as -7<0>+7

    #73285
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • β˜…β˜…

    ok, i see how that last section works – this is ok as long as
    all values incoming are β€˜literal’, and i don’t have to deal
    with any β€˜mapped’ offsets ie: pan with midi value 0-14 where it
    is displayed as -7<0>+7

    As you know, in such a case -7 to +7 are actually the values 0-14 so as far as midi and the D-110 are concerned. It’s only at the interface level that you would need to display -7 – +7 and in fact 0 to the D-110 would be 7 for the control at that address (you know this, but someone else reading this might not). That’s where you would use uiFixedSlider etc.

    I suppose there could be some reason to convert the midi values 0,1 to -7, -6 etc in lua (ie sending text to uiLabel), but for pure sending of midi and receiving I don’t think it is necessary πŸ™‚

    in practice, i will have to split this read-off of values from
    the incoming data whenever i…

    Sometimes you may want to load every byte into a table and then run various functions on the address stored in the table rather than run a series of if/else on every midi-data-byte. But either would work.

    i wanted to play with it without it being a Ctrlr midi
    message type – because that seems to require it to be a message
    incoming on the midi bus.(if you see what i mean..)

    Do you mean doing all this without being connected to the D-110? No doubt that makes it a bit more difficult to test, but maybe you could set up a program like Midi-Ox to transmit sysex messages to your panel? πŸ˜•

    #73286
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    yup point/s taken – this little demo panel, though,
    is/was merely a test thing – a ‘paraphrasing’, ..a simili !
    hard day’s painting&decorating today, so if i recover from
    that and get some inspiration, i’ll have a go at getRange().
    my 6am sessions are on hold at the moment because i tend to
    forget i’m supposed to go to work if i start up Ctrlr πŸ˜‰

    #73291
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    tried the last code thing, loads of ways πŸ™‚ didn’t compile
    – but doesn’t matter: there’s a very nice example in this
    tg33 panel that was posted in september, i should be able to
    work from that, for the D-110 panel.

    just for now, i’m going to focus (for the hell of it…but do
    i really need to do this? whatever: just want to see how to
    do it…) on splitting this big 80’byte’ string into 4 separate
    20’byte’ strings, and send them to the labels.
    (i realise this has little to do with the midi receive routine,
    but it will make sense of this panel ..aargh, getting lost here,
    never mind: i’ve found my thing for the D-110, gotta finish that
    thing.)

    #73293
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • β˜…β˜…

    this little demo panel, though,
    is/was merely a test thing – a β€˜paraphrasing’, ..a simili !

    Oh I see, but it’s all very interesting and for me and leads to greater understanding generally. πŸ™‚

    #73297
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    okay, playtime again. had fun trying that untested script:
    it made Ctrlr crash in a loop, as i tried it πŸ™‚
    so i had to delete Ctrlr roaming settings..

    anyway: so, inspired by the TG33 midiReceived, i had
    another go at splitting the ‘big’ string with getRange()
    -so far, just trying to have a look at what can be sent
    to console. getting wrong data, evidently. best thing to
    do is have a look at the getBank method(annotated, with
    all previous junk in it).
    nb: the reason i’m trying to go via memory block is that
    you can getSize() on it (whereas i couldn’t with other
    attempts)

    it is then able to getRange() – at this point i send each
    one to console, and get – ? – wrong data type, anyway.

    > all i would like to do right now is see the ‘big’ string
    split into 4 separate strings – i know this isn’t specifically
    hex at this stage, just text.

    i s’pose i’m mixing stuff up here, aren’t i?
    (i need an empty day to get into this properly)

    #73298
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • β˜…β˜…

    Hi there Human Fly,

    I have got that code working from above. See panel. Here I am sending a made-up Sysex string …

    F0 41 10 16 12 03 00 00 00 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 41 F7

    … from MidiOx to trigger the midi received function in the panel using virtual midiports (LoopMidi).

    Enjoy!

    πŸ™‚

    Attachments:
    You must be logged in to view attached files.
    #73308
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    hey, ok thanks. will load it up in a minute.

    here’s another version of what i was doing, from this morning
    (see below) – if you look at the getBank method, you’ll see what
    i’ve been trying: managed to generate two separate strings from
    the ‘big’ one – read to console only atm. but for some reason,
    i don’t get all four, and didn’t have time to check the bytes to
    see if they corresponded – hope it makes sense if you look at it.

    need to tidy this up before i try again(loads of commented-out
    stuff in there, things i tried/failed with)

    Attachments:
    You must be logged in to view attached files.
    #73310
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    mmm? i tried your panel – my onboard midi interface is loopbe1, how
    i link to midiox. didn’t get anything there yet. but i’m going to
    look at it more closely.

    can we look at this splitting of a string into 4 strings thing?
    i call the string content ‘extBank’, then i make a memory block
    of that, so i can getSize – the way you can with a midi message –
    (not essential, but just so i can ‘tick that box’)

    if i do memB toHexString, i don’t get hex data, i get something
    else – so i’ve skipped that.

    instead, i’m doing:

    prog1Data 	= memB:getRange(1,20)
    preset1 = prog1Data:toHexString(1)
    	console("preset1 :"..preset1)

    and the same, through prog2data, prog3data, prog4data.
    what i get back is prog1 has 20 bytes, but starts at
    byte2 (misses the first one), and then all the rest of
    the data is in prog2, and prog3 + 4 have nothing.
    and i’m not getting any errors.
    confoooosed πŸ™‚

    thinking: if i can get the ‘data’ with these, it should
    be possible to send it to the label slots that the presets
    refer to…. -?- (hey just for kicks)

    #73311
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    i will say that i’m liking the tg33 panel midi received method.
    Peter Scheidt says that calling modulators by VST Index was his
    best option – i do like the idea of having a common ID system:
    it means building the entire thing and numbering it before you
    can test – which is a bit daunting when you haven’t yet attributed
    all of your VST Index #s

    look at the D-110 .. when you’ve got a synth wave selected, it’s
    the same MIDI parameter # as the PCM Bank: you end up with 2 objects
    to select the same parameter, which will necessarily have different
    VST index numbers, so when you give a quick headcount of your parameters,
    *it won’t correspond* aargh: i should know by now how many parameters
    each partial has, i think it’s 58, not counting the Common params.
    um, i’d like to sidestep that for the time being; i’m still pondering
    some layout issues on that one.

    #73312
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    yesss. grrrrr ! πŸ˜€ sussed it. getRange numbers are not
    start and end, it’s start, the the number of items. so
    it’s done like this: (note i had to specify start minus 1)
    `prog1Data = memB:getRange(1-1,20)
    preset1 = prog1Data:toHexString(1)
    console(“preset1 :”..preset1)

    prog2Data = memB:getRange(21-1,20)
    preset2 = prog2Data:toHexString(1)
    console(“preset2 :”..preset2)

    prog3Data = memB:getRange(41-1,20)
    preset3 = prog3Data:toHexString(1)
    console(“preset3 :”..preset3)

    prog4Data = memB:getRange(61-1,20)
    preset4 = prog4Data:toHexString(1)
    console(“preset4 :”..preset4)`

    and that produces (in console):

    LUA>> midiMessageReceived: 80bytes
    LUA>> bank dump detected!
    LUA>> preset1 :6f 6e 65 20 20 20 20 20 20 20 2a 33 59 64 34 00 78 7f 62 4e
    LUA>> preset2 :74 77 6f 20 20 20 20 20 20 20 74 3b 64 59 08 51 7f 7c 3c 2b
    LUA>> preset3 :74 68 72 65 65 20 20 20 20 20 55 12 7f 3b 0f 11 2b 60 58 19
    LUA>> preset4 :66 6f 75 72 20 20 20 20 20 20 55 5d 3b 2e 69 51 7f 7c 3c 2b

    he he.

    (‘code’ buttons not working tonight)

    #73313
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    more: have tidied up script into a re-usable:

    function restoreBank()
    
    	-- This variable stops index issues during panel bootup
    	if panel:getRestoreState() == true or panel:getProgramState() == true then
    		return
    	end
    
    -- retrieving BankA
    	bankA = L(panel:getModulatorByName("lcd_bankDataA"):getComponent():getProperty("uiLabelText"))
    
    	local memB = MemoryBlock(bankA)
    
    	local size = memB:getSize()
    
    	if size == 80 then
    
    	local prog1Data 	= memB:getRange(0,20)
    	local preset1 = prog1Data:toHexString(1)
    
    	local prog2Data 	= memB:getRange(20,20)
    	local preset2 = prog2Data:toHexString(1)
    
    	local prog3Data 	= memB:getRange(40,20)
    	local preset3 = prog3Data:toHexString(1)
    
    	local prog4Data 	= memB:getRange(60,20)
    	local preset4 = prog4Data:toHexString(1)
    
    	panel:getComponent("lcd_presetData1"):setPropertyString("uiLabelText",""..preset1)
    	panel:getComponent("lcd_presetData2"):setPropertyString("uiLabelText",""..preset2)
    	panel:getComponent("lcd_presetData3"):setPropertyString("uiLabelText",""..preset3)
    	panel:getComponent("lcd_presetData4"):setPropertyString("uiLabelText",""..preset4)
    	end
    end

    here’s another version of the panel – it can write to the external, receive it,
    and restore previous now. still a bit fiddly to observe this but does work.
    probably on the wrong track re: midi and preset routines but does what i set
    out to do (so far). ‘send prog’ is now an idea for copying presets/data?

    Attachments:
    You must be logged in to view attached files.
    #73315
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    edit: woops, messed that up somehow (at least here),
    i think that file has wrong methods triggered by wrong
    buttons – try this one instead:
    (mods if you can delete the previous file; i can’t remove it)

    >quickest test is to toggle ‘recv’ and ‘restore’ pressing the
    same ‘preset’ buttons each time: you see the data changing in
    the preset windows that contain the settings of the faders.

    Attachments:
    You must be logged in to view attached files.
    #73326
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    when collecting values with a table,
    i noticed a difference in output when i do memB(getByte,n)
    and tableX[n]: getByte produced the wrong values, whereas
    table is correct. so what format will getByte produce? hex?
    table[n] seems to give me the literal values.

    um, i suppose when i do concatenatation and then a memory block,
    i’m producing a string?

    #73327
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    ok, never mind, figured out what it was: needed to getByte
    from the labels. now transfers all four presets:
    (see panel/send single method>orange ‘send’ button)

    (lol, not convinced any of this is necessary but whatever…
    it’s practice)

    Attachments:
    You must be logged in to view attached files.
    #73329
    human fly
    Participant
    • Topics: 124
    • Replies: 1070
    • Total: 1194
    • β˜…β˜…β˜…β˜…

    good job i uploaded because i scr***d up just after that,
    and it wouldn’t load at all πŸ™‚ (turns out i forgot to
    rename function titles after copying – was able to fix it
    in notepad > method name vs -duplicate- function title conflict?)
    – last version wasn’t copying names, does now.

    there is now a virtual ‘external device’ receiving data.
    need to sort this out properly now.

    Attachments:
    You must be logged in to view attached files.
    #73331
    dnaldoog
    Participant
    • Topics: 4
    • Replies: 480
    • Total: 484
    • β˜…β˜…

    Hey Human Fly,

    I finally worked out how to split a 240 byte string (e.g. direct from uiTextLabel) into 4 segments.

    
    mySplitString = function(mod,value,source)
        a=panel:getModulatorByName("stringtosplit"):getComponent():getProperty("uiLabelText")
        local st = mySplitStringIntoFourSegments(a,60)
        for i,v in ipairs(st) do
            console(String(i.."[".. v.."]"))
            panel:getComponent("string0"..i):setPropertyString("uiLabelText",v)
        end
    end --function
    ------------------------------------
    function myTrim(s) -- trim leading/trailing whitespace
        return (s:gsub("^%s*(.-)%s*$", "%1"))
    end --function
    -----------------------------------
    function mySplitStringIntoFourSegments(text, stringSize)
        local j=1 -- counts to 4
        local s = {}
        for i=1,#text,stringSize do
            s[j] = myTrim(string.sub(text,i,stringSize*j))
            j=j+1
        end
        return s
    end --function
    -----------------------------------
    

    πŸ™‚

    With regard to that panel I posted, did you unmute loopBe1?

Viewing 20 posts - 41 through 60 (of 71 total)
  • The forum ‘Using Ctrlr’ is closed to new topics and replies.
There is currently 0 users and 46 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