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 49 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