Help getting ASCII Characters into uiLabel

Home Forums General Programming Help getting ASCII Characters into uiLabel

Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • #118219
    spiffo
    Participant
      • Topics: 12
      • Replies: 38
      • Total: 50

      OK, I’ve hit a bit of brick wall with this one so hopefully some nice person can shed some light!

      I have a Yamaha DX11 here and I have successfully managed to capture the SysEx it spits out when you change Patches and to route them through to some uiSliders on my panel, but I am having problems trying to extract the 10 Bytes of Data that represent the Patch Name and get them to display in the Panel.

      Below is part of my LUA script which is relevant to building the Patch Name and spitting it out to the Console:

      if size == 101 then

      PatchDataLoaded = midiMessage:getData()

      VCED_Data = midiMessage:getData():getRange(6,94)

      — Extracting the Patch Name Characters & assigning them to variables char1, char2 …etc

      char1 = string.char(VCED_Data:getByte(76))
      char2 = string.char(VCED_Data:getByte(77))
      char3 = string.char(VCED_Data:getByte(78))
      char4 = string.char(VCED_Data:getByte(79))
      char5 = string.char(VCED_Data:getByte(80))
      char6 = string.char(VCED_Data:getByte(81))
      char7 = string.char(VCED_Data:getByte(82))
      char8 = string.char(VCED_Data:getByte(83))
      char9 = string.char(VCED_Data:getByte(84))
      char10 = string.char(VCED_Data:getByte(85))

      getPatchName = char1..char2..char3..char4..char5..char6..char7..char8..char9..char10

      console (“Assigning patch name:”..getPatchName)

      assign_VCED_Values(midiMessage,false)

      else

      console (“Byte Sizes Incorrect”)

      end

      Now as I understand it, string.char converts Hex into ASCII, so that code should construct an ASCII String which is 10 letters long in a Variable called getPatchName?

      Except all I seem to get on the Console and in the uiLabel is 10 Blanks!

      Is there some where else I need to define what Hex Code translates to what ASCII Code, or am I just going about this all the wrong way?

      • This topic was modified 3 years, 11 months ago by spiffo.
      #118222
      shooking
      Blocked
        • Topics: 14
        • Replies: 60
        • Total: 74

        this is what I do

        
          console("processSingleD calling generatePatchPrefix")
        
            getPatchName = generatePatchPrefix(patch, string.format("%.10s", d:getRange(0,10):toString()))
        
            console("[["..getPatchName.."]]")
        

        so i see you know the range of values for your chars. 76 – 85 == 10 chars like my K1r.

        
          console("generatePatchPrefix")
        
            getPatchName = generatePatchPrefix(patch, string.format("%.10s", VCED_Data:getRange(76,10):toString()))
        
            console("[["..getPatchName.."]]")
        

        I _think_ that might work … try it in the console .. SAVE YOUR WORK BEFORE YOU DO IT … I have bitter experience recently of Ctrlr crashing and nuking my Lua.

        #118223
        shooking
        Blocked
          • Topics: 14
          • Replies: 60
          • Total: 74

          I typed too fast .. of course you dont need to generate a patch prefix!!

          
          
            console("generatePatchPrefix")
          
              getPatchName = string.format("%.10s", VCED_Data:getRange(76,10):toString())
          
              console("[["..getPatchName.."]]")
          

          sorry about that. so the idea is use the format to restrict to 10 chars (the %.10s)
          grab range of bytes you want … start at 76 and get 10 .. turn that to a string .. put that into variable print variable.

          Hope this works for you

          #118224
          spiffo
          Participant
            • Topics: 12
            • Replies: 38
            • Total: 50

            OK, so that seems a lot more elegant, use string.format to form a 10 Character String from 10 Bytes starting at Byte 76 in my Memory Block called VCED_Data !

            I’m trying to learn this LUA as I go along, basically winging it by copying bits of code, trial & error, and some programming knowledge from way back in school.

            Yep I’ve got the Yamaha MIDI Implementation in front of me, I can follow most of it and with a bit of Trial & Error I’ve managed to work out which Byte is which. I’ve managed to extract the correct Bytes to throw at the right uiSliders. But this afternoon I just couldn’t get that HEX Code converted to ASCII and displayed in a uiLabel, I’ll give your method a go first thing tomorrow.

            Thanks!

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

              I don’t think you need string.format, but it’s certainly interesting and something I didn’t know about.

              getPatchName =VCED_Data:getRange(76,10):toString()

              • This reply was modified 3 years, 11 months ago by dnaldoog.
              #118246
              shooking
              Blocked
                • Topics: 14
                • Replies: 60
                • Total: 74

                depends what you want … in my day job you would be surprised the amount of chaos caused by overwriting bounds.
                Lua and luabind cause rather a lot of havoc to the C/C++ … so I figure explicitly limiting stuff might be ok.
                There again if Lua strings work like more modern languages then it will just keep adding length on until you run out of memory … except often times I am moving data into a memory block and for sure that doesnt keep extending :-))

                >>> console(string.format(“[[%.10s]]”, “hi”))
                [[hi]]

                >>> console(string.format(“[[%.10s]]”, “hiIamAlongstringhaha”))
                [[hiIamAlong]]

                >>> console(string.format(“[[%.10s]]”, “012345678901234567890”))
                [[0123456789]]

                Now since posting this I have had to roll back to 5.3 and it behaves quite differently to 6.x

                Spiffo – when you say “My memory block VCED_Data” can you post how you created it please?

                What I am finding is with 5.3 I have to “loop” whereas with 6.x I can use range operators.
                The key difference is I dont seem able to create a MemoryBlock in 5.3 but can create a CtrlrLuaMemoryBlock.
                The latter appears to behave quite differently to a MemoryBlock — copyTo dont work the same OR I am just confusing myself.

                #118247
                shooking
                Blocked
                  • Topics: 14
                  • Replies: 60
                  • Total: 74

                  Here’s what I had to hack … man if someone would be so kind to help me build 6.x on Linux I am sure I can help to make it more stable!

                  Or how to use MemoryBlock in 5.3 – these CtrlrLuaMemoryBlock behave differently – I am sure I am missing an L somewhere ??

                  
                  --      /* idx:    0 */  	char	Name[10];		// PatchName 
                      local name = ""
                  
                  --    name = string.format("%.10s", d:getRange(0,10):toString())
                  	for i = 0, 9 do
                  		console("[[inval_"..i.."]] == [["..d.."]]")
                  		console(""..d[1])
                      	name = name..string.char(d)
                  

                  clearly the 6.x method using MemoryBlock is far cleaner than what I am doing with 5.3

                  If anyone an spot an obvious mistake I am making and they are near me in UK I will “socially distance” them a beer 🙂

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

                    Hi shooking,

                    ‘d’ is a MemoryBlock object, so to access each byte, you need d:getByte(i) not d[ i ] the latter being a reference to an index of a non-existent lua table.

                    
                    d=MemoryBlock("68 69 49 61 6D 41 6C 6F 6E 67 73 74 72 69 6E 67 68 61 68 61")
                    
                       name = string.format("%.10s", d:getRange(0,10):toString())
                    
                    console(name) --hiIamAlong
                    
                    	for i = 0, 9 do
                    		console("[[inval_"..i.."]] == [["..d:getByte(i).."]]")
                    		console(""..d:getByte(i))
                        	name = name..string.char(d:getByte(i))
                    end
                    
                    console(name) -- hiIamAlonghiIamAlong
                    

                    Also in lua, you can do

                    console(String(string.sub("hiIamAlongstringhaha",1,10))) instead of ` console(string.format(“[[%.10s]]”, “hiIamAlongstringhaha”)) but I guess they both produce the same output.

                    • This reply was modified 3 years, 11 months ago by dnaldoog.
                    #118256
                    dnaldoog
                    Participant
                      • Topics: 4
                      • Replies: 480
                      • Total: 484
                      • ★★

                      Hi shooking,

                      copyTo and copyFrom seem to crash Ctrlr.

                      I would use ‘append`

                      d=MemoryBlock("68 69 49 61 6D 41 6C 6F 6E 67 73 74 72 69 6E 67 68 61 68 61")
                      e=MemoryBlock()
                      
                      e:append(d)
                      console("size\t"..e:getSize())
                      
                      size   20
                      

                      I think CtrlrLuaMemoryBlock is deprecated, but not sure what that really means.

                      • This reply was modified 3 years, 11 months ago by dnaldoog.
                      #118272
                      shooking
                      Blocked
                        • Topics: 14
                        • Replies: 60
                        • Total: 74

                        So what I found is in the 6.x version (which I was using thinking latest is greatest) the copyTo etc can work.
                        I will try the append.
                        Right now with my debugging hints I can see my 5.x panel is failing on what seems to be 6.x specific stuff .. bummer.

                        In process of getting my head around it, lighting BBQ, drinking beer and cooking some seriously seasoned chicken – from my Miniaktools secret lair I can use my PC and look out at progress from my pseudo pit …

                        Really want to get this memory block peacefully coexisting with MidiData.

                        #118273
                        shooking
                        Blocked
                          • Topics: 14
                          • Replies: 60
                          • Total: 74

                          what’s smart way of appending a range?
                          So I read in raw Sysex from K1r.
                          I then strip of the first header 8 bytes (because I can regenerate those), the last but one and F7 byte (checksum and trailing)

                          so my MemoryBlocks are what 10 bytes smaller than the raw sysex.

                          I just want to take the range 0, 8 [[ from 0 for 8 bytes]] from original midiMessage.
                          Then I want to create a block with the residual – 2.
                          And from there on I want to reference new blocks as 0 for 1st byte (ie the first char of the name).

                          This worked in 6.0 … but then I hit various snags — backporting to 5.3 is messing with my head 🙂

                          #118274
                          shooking
                          Blocked
                            • Topics: 14
                            • Replies: 60
                            • Total: 74

                            zB does this seem legitimate?

                            
                                        local d1 = MemoryBlock()
                            	    d1:append(d:getRange(0, gMULTIPLE_SINGLE_SYSEX_TRAN))
                                        
                                        local d2 = d:getRange(gMULTIPLE_SINGLE_SYSEX_TRAN, gMULTIPLE_SINGLE_SYSEX_TRAN)
                                        local d3 = d:getRange(2 * gMULTIPLE_SINGLE_SYSEX_TRAN, gMULTIPLE_MULTI_SYSEX_TRAN)
                            

                            ie I am testing the append range of d into empty d1 – you see the way I did it in 6.x and it seemed to work (for d2 and d3)

                            #118276
                            shooking
                            Blocked
                              • Topics: 14
                              • Replies: 60
                              • Total: 74

                              Ah … I dont mean to contradict you my friend but I will – because clearly I didnt share everything with you.

                              I am creating a Multi dimensional array

                              
                                  SINGLE_SYSEX_STORAGE_SIZE = 88
                                  g_singlePatch = {}
                                  for i = 0, 63 do
                              --[[
                              		version 6 has a true parameter, 5 does not
                              --        g_singlePatch = MemoryBlock(SINGLE_SYSEX_STORAGE_SIZE, true)
                              --]]
                                      g_singlePatch = MemoryBlock(SINGLE_SYSEX_STORAGE_SIZE)
                                  end
                              
                              --
                              --  32 slots for multis
                              --  deliberately starting from 0 - could start from 64? Examine sysex and make decision
                              --  recall the number == patch, so no need to store header nor F7
                                  g_multiPatch = {}
                                  -- let store it as 32
                                  -- note 76 data -- strip of Sysex Header and F7
                                  MULTI_SYSEX_STORAGE_SIZE = 76
                                  for i = 0, 31 do
                              --[[
                              		version 6 has a true parameter, 5 does not
                              --        g_multiPatch = MemoryBlock(MULTI_SYSEX_STORAGE_SIZE, true)
                              --]]
                                      g_multiPatch = MemoryBlock(MULTI_SYSEX_STORAGE_SIZE)
                                  end
                              

                              You can see my my comments I am pulling what’s left of my hair out 🙂
                              So I read in d =midiMessage:getData

                              We all agree this has MemoryBlock type semantics.
                              But see later I want to “copyTo” .. and in 6.x this works great.
                              But in 5.3 it doesnt seem to (or I am doing it wrong).

                              So I process according to this stack:

                              
                              05/08/20 18:49:27       [FILE: [string "requestSinglePatch"]]:          Line: 8         FUNC:
                              05/08/20 18:49:27       [TRACEBACK]
                              05/08/20 18:49:27       [FILE: [string "handlePanelMidiMessage"]]:              Line: 11                FUNC:
                              05/08/20 18:49:27       [Handling sysex size 97 bytes]
                              05/08/20 18:49:27       [TRACEBACK]
                              05/08/20 18:49:27       [FILE: [string "handleKawaiSysex"]]:            Line: 20                FUNC: handleKawaiSysex
                              05/08/20 18:49:27       [FILE: [string "handlePanelMidiMessage"]]:              Line: 66                FUNC:
                              05/08/20 18:49:28       [Handling size 97 bytes.]
                              05/08/20 18:49:28       [TRACEBACK]
                              05/08/20 18:49:28       [FILE: [string "processSingleD"]]:              Line: 303               FUNC: processSingleD
                              05/08/20 18:49:28       [FILE: [string "handleKawaiSysex"]]:            Line: 129               FUNC:
                              05/08/20 18:49:28       [FILE: [string "handlePanelMidiMessage"]]:              Line: 66                FUNC:
                              05/08/20 18:49:28       [TRACEBACK]
                              05/08/20 18:49:28       [FILE: [string "processSingleD"]]:              Line: 4         FUNC: validateSysexHeader
                              05/08/20 18:49:28       [FILE: [string "processSingleD"]]:              Line: 305               FUNC:
                              05/08/20 18:49:28       [FILE: [string "handleKawaiSysex"]]:            Line: 129               FUNC:
                              05/08/20 18:49:28       [FILE: [string "handlePanelMidiMessage"]]:              Line: 66                FUNC:
                              05/08/20 18:49:33       [d is not empty]
                              05/08/20 18:49:38       [TRACEBACK]
                              05/08/20 18:49:38       [FILE: [string "processSingleD"]]:              Line: 50                FUNC: process_one_single
                              05/08/20 18:49:38       [FILE: [string "processSingleD"]]:              Line: 332               FUNC:
                              05/08/20 18:49:38       [FILE: [string "handleKawaiSysex"]]:            Line: 129               FUNC:
                              05/08/20 18:49:38       [FILE: [string "handlePanelMidiMessage"]]:              Line: 66                FUNC:
                              05/08/20 18:49:38       [TRACEBACK]
                              05/08/20 18:49:38       [FILE: [string "generatePatchPrefix"]]:         Line: 3         FUNC: generatePatchPrefix
                              05/08/20 18:49:38       [FILE: [string "processSingleD"]]:              Line: 77                FUNC:
                              05/08/20 18:49:38       [FILE: [string "processSingleD"]]:              Line: 332               FUNC:
                              05/08/20 18:49:38       [FILE: [string "handleKawaiSysex"]]:            Line: 129               FUNC:
                              05/08/20 18:49:38       [FILE: [string "handlePanelMidiMessage"]]:              Line: 66                FUNC:
                              05/08/20 18:49:38       [TRACEBACK]
                              05/08/20 18:49:38       [FILE: [string "handleKawaiSysex"]]:            Line: 6         FUNC: bankChange
                              05/08/20 18:49:38       [FILE: [string "handleKawaiSysex"]]:            Line: 139               FUNC:
                              05/08/20 18:49:38       [FILE: [string "handlePanelMidiMessage"]]:              Line: 66                FUNC:
                              05/08/20 18:49:38       [TRACEBACK]
                              05/08/20 18:49:38       [FILE: [string "processSourceMode"]]:           Line: 11                FUNC:
                              

                              And if you saw my earlier post this is a developing stack of what I am doing.

                              So hopefully one can see I request a single
                              The Sysex I send out is caught by my handleMidiMessage.
                              It filters based on size then header content.
                              And dispatches to handleKawaiSysex because it has that manufactures reserved ID.
                              We see 97 bytes come in … so we go to next function in the stack ..processSingleD — because this 97 is the exact size of a SYSEX dump for an individual single.

                              And one can see further this calls a method in same file validateSysexHeader. It’s good.
                              So then we drop back into processSingleD which calls process_one_single. (line 50 of processSingleD).
                              He generatepathcPrexi and eventually that cpmpletes, pops stakc, pops state and I am done.

                              The complexity that you couldnt have seen

                              handlePandelMidiMessage … d is == MidiMessage:getData()
                              that is passed into handleKawaiSysex

                              
                                         end
                                      elseif handleKawaiSysex(d, size, false) == true then
                                          -- cool it worked
                                          return 1
                                      else
                              

                              who then passes this (via my debug we can see)

                              
                              05/08/20 18:49:28       [FILE: [string "handleKawaiSysex"]]:            Line: 129               FUNC:
                              ...
                              
                                     elseif size == gSINGLE_SYSEX_TRAN then
                              
                                          debugConsole("received single single")
                              
                                          worked = processSingleD(d, true)   <<<<<<< this is line 129
                              
                                          if worked == true and fromFile == true then
                                              -- send to synth
                                             	utils.warnWindow("\n\nINFO", "About to load Single into K1.")
                                              console("sending 1")
                                              panel:sendMidiMessageNow(CtrlrMidiMessage(d))
                                          end
                                          debugConsole("Endreceived single single")
                                          local bias = d:getByte(7)
                                          bankChange(bias)
                                      end
                                  end
                              

                              so d is still a form of MidiMessage but then the fun starts
                              Here I convert the subset into a Lua table .. so now I do need the square brackets

                              
                              
                              function processSingleD(--[[ CtrlrLuaMemoryBlock --]] d,
                                      --[[ bool --]] singlePatch )
                                  console("in processSingleD")
                              	g_debugFile = openDebugFile()
                              	whereAmI(g_debugFile, __DFUNC__())
                                  debugConsole("in processSingleD")
                                  if validateSysexHeader(d, singlePatch) == false then
                                      debugConsole("invalid sysex header")
                                      return false
                                  end
                              
                              	debugConsole("single sysex header was valid", true)
                              
                                  if singlePatch == true then
                                      debugConsole("Single")
                                      local size = d:getSize()
                                      local patch = d:getByte(7)
                                      debugConsole(""..patch)
                                      console("single "..patch)
                                      local lp
                              
                                      -- skip the F0 
                                      -- first 8 bytes and we dont and the F7 and index is a 0 not 1
                              		debugConsole("about to copyTo", true)
                              
                              		for i=0, SINGLE_SYSEX_STORAGE_SIZE -1 do
                              			g_singlePatch[patch] = d:getByte(8 + i)
                              		end
                              
                                      debugConsole(string.format("Single %d", size))
                                      debugConsole(string.format("Single %d", g_singlePatch[patch]:getSize() ))
                              

                              and from now on I need to not use getByte … well maybe I cna use it but it doesnt seem to work because I am a 2 dimensional MemoryBlock.

                              Simply to say there was no way you could have know that – and this explains why d[ noti ] references noti byte from d. It’s a MeoryBlock that contains wnother memory block

                              
                              >>> console(what(g_singlePatch[0]))
                              Object type [MemoryBlock]
                              -----------------------------------------------------------------
                              
                              Members:
                              	                       getData:	function
                              	                   setBitRange:	function
                              	                       getByte:	function
                              	             loadFromHexString:	function
                              	                   toHexString:	function
                              	               insertIntoTable:	function
                              	                       setSize:	function
                              	                      fillWith:	function
                              	                        insert:	function
                              	                       setByte:	function
                              	                       getSize:	function
                              	                      getRange:	function
                              	                 removeSection:	function
                              	               createFromTable:	function
                              	                      swapWith:	function
                              	                    ensureSize:	function
                              	                   getBitRange:	function
                              	                        copyTo:	function
                              	                   replaceWith:	function
                              	                        __init:	function
                              	                      copyFrom:	function
                              	                      toString:	function
                              	                        append:	function
                              	            fromBase64Encoding:	function
                              	              toBase64Encoding:	function
                              	                    toLuaTable:	function
                              
                              Attributes:
                              
                              -----------------------------------------------------------------
                              Object type [MemoryBlock]
                              -----------------------------------------------------------------
                              
                              Members:
                              	                       getData:	function
                              	                   setBitRange:	function
                              	                       getByte:	function
                              	             loadFromHexString:	function
                              	                   toHexString:	function
                              	               insertIntoTable:	function
                              	                       setSize:	function
                              	                      fillWith:	function
                              	                        insert:	function
                              	                       setByte:	function
                              	                       getSize:	function
                              	                      getRange:	function
                              	                 removeSection:	function
                              	               createFromTable:	function
                              	                      swapWith:	function
                              	                    ensureSize:	function
                              	                   getBitRange:	function
                              	                        copyTo:	function
                              	                   replaceWith:	function
                              	                        __init:	function
                              	                      copyFrom:	function
                              	                      toString:	function
                              	                        append:	function
                              	            fromBase64Encoding:	function
                              	              toBase64Encoding:	function
                              	                    toLuaTable:	function
                              
                              Attributes:
                              

                              and most of the above methods, like you said, are suspect. ie copyTo should work but it doesnt. But on 6.x is does 🙂

                              I am hence using old school scalars to work with my vectors.

                              When I tried

                              
                              	local	name=""
                              	for i = 0, 9 do
                                  	name = name..string.char(d)
                              		if d == d:getByte(i) then
                              			console("d is same as d:getByte(i)")
                              		else
                              			console("d is DIFFERENT as d:getByte(i)")
                              		end
                              	end
                              

                              it crashes because for sure dLgetByte(i) is not what one expects
                              And when I comment it out my code works again

                              
                              	local	name=""
                              	for i = 0, 9 do
                                  	name = name..string.char(d)
                              --[[
                              		if d == d:getByte(i) then
                              			console("d is same as d:getByte(i)")
                              		else
                              			console("d is DIFFERENT as d:getByte(i)")
                              		end
                              --]]
                                      end
                              
                              #118277
                              shooking
                              Blocked
                                • Topics: 14
                                • Replies: 60
                                • Total: 74

                                Hey dnaldoog … I thank you from the bottom of my heart (if I have one :-()

                                So once I realized the semantics of my d -> d … well I renamed them d, mb_d and used d:getByte(i) v mb_d.

                                What do you know … my 5.3 seems to be working very similar to 6.x before it crashed and stole my Lua.

                                Chicken and more beer awaits but thank the Lord, and you, that I found my logic errors.

                                I do hope there is an easier way to get the debug like I showed in another post.
                                BUT it did help to track down this issue.

                                Thanks again whichever continent you are on .. I have to figure it’s the other side of The Pond 🙂
                                Cheer and now time to reflect on events of 75 years ago.

                              Viewing 14 posts - 1 through 14 (of 14 total)
                              • The forum ‘Programming’ is closed to new topics and replies.
                              There is currently 0 users and 70 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