Home Forums General Programming getSize only looking at last byte number

This topic contains 19 replies, has 4 voices, and was last updated by Possemo Possemo 2 months, 2 weeks ago.

Viewing 20 posts - 1 through 20 (of 20 total)
  • Author
    Posts
  • #72722

    EnzoF04
    Participant

    so i’m doing this:

    --  getting midiMessage data into a MemoryBlock in a midiReceived function
    	myData1 = MemoryBlock(midiMessage:getLuaData())
    	myDataSize = myData1:getSize()
    	console ("Block size = "..tostring(myDataSize))
    
    --  datablock sample parameters
    	myDataBlock0 = MemoryBlock(midiMessage:getLuaData():getRange(0,18))
    	myDataBlock0Bnum = myDataBlock0:getByte(0)
    	console ("myDataBlock0 number = "..tostring(myDataBlock0Bnum))
    	myDataBlock0Size = myDataBlock0:getSize()
    	console ("myDataBlock0 size = "..tostring(myDataBlock0Size))
    	console (myDataBlock0:toHexString(1))
    
    --  datablock sample part 01
    	myDataBlock1 = MemoryBlock(midiMessage:getLuaData():getRange(19,140))
    	myDataBlock1Bnum = myDataBlock1:getByte(0)
    	console ("myDataBlock1 number = "..tostring(myDataBlock1Bnum))
    	myDataBlock1Size = myDataBlock1:getSize()
    	console ("myDataBlock1 size = "..tostring(myDataBlock1Size))
    	console (myDataBlock1:toHexString(1))
    
    --  datablock sample part 02
    	myDataBlock2 = MemoryBlock(midiMessage:getLuaData():getRange(141,262))
    	myDataBlock2Bnum = myDataBlock2:getByte(0)
    	console ("myDataBlock2 number = "..tostring(myDataBlock2Bnum))
    	myDataBlock2Size = myDataBlock2:getSize()
    	console ("myDataBlock2 size = "..tostring(myDataBlock2Size))
    	console (myDataBlock2:toHexString(1))

    What (in my opinion) goes wrong is that i don’t get the size of the block i specify. for myDataBlock1 I’m specifying a range from 19 – 140 = 121 bytes. Console tells me that myDataBlock1 has a size of 140. And even further, myDataBlock2 has a size of 262. This is the console output:

    myDataBlock0 number = 240
    myDataBlock0 size = 18
    f0 7e 01 04 00 0c 31 63 07 68 02 00 00 00 00 68 02 00
    myDataBlock1 number = 0
    myDataBlock1 size = 140
    00 40 00 4d 24 5a 00 65 4c 6f 44 77 34 7c 6c 7f 50 7f 50 7c 6c 77 34 6f 44 65 4c 5a 00 4d 24 40 00 32 58 25 7c 1a 30 10 38 08 48 03 10 00 2c 00 2c 03 10 08 48 10 38 1a 30 25 7c 32 58 40 00 4d 24 5a 00 65 4c 6f 44 77 34 7c 6c 7f 50 7f 50 7c 6c 77 34 6f 44 65 4c 5a 00 4d 24 40 00 32 58 25 7c 1a 30 10 38 08 48 03 10 00 2c 00 2c 03 10 08 48 10 38 1a 30 25 7c 32 58 00 01 40 00 4d 24 5a 00 65 4c 6f 44 77 34 7c 6c 7f 50 7f
    myDataBlock2 number = 1
    myDataBlock2 size = 262
    01 40 00 4d 24 5a 00 65 4c 6f 44 77 34 7c 6c 7f 50 7f 50 7c 6c 77 34 6f 44 65 4c 5a 00 4d 24 40 00 32 58 25 7c 1a 30 10 38 08 48 03 10 00 2c 00 2c 03 10 08 48 10 38 1a 30 25 7c 32 58 40 00 4d 24 5a 00 65 4c 6f 44 77 34 7c 6c 7f 50 7f 50 7c 6c 77 34 6f 44 65 4c 5a 00 4d 24 40 00 32 58 25 7c 1a 30 10 38 08 48 03 10 00 2c 00 2c 03 10 08 48 10 38 1a 30 25 7c 32 58 00 02 40 00 4d 24 5a 00 65 4c 6f 44 77 34 7c 6c 7f 50 7f 50 7c 6c 77 34 6f 44 65 4c 5a 00 4d 24 40 00 32 58 25 7c 1a 30 10 38 08 48 03 10 00 2c 00 2c 03 10 08 48 10 38 1a 30 25 7c 32 58 40 00 4d 24 5a 00 65 4c 6f 44 77 34 7c 6c 7f 50 7f 50 7c 6c 77 34 6f 44 65 4c 5a 00 4d 24 40 00 32 58 25 7c 1a 30 10 38 08 48 03 10 00 2c 00 2c 03 10 08 48 10 38 1a 30 25 7c 32 58 00 03 40 00 4d 24 5a 00 65 4c 6f 44 77 34 7c 6c 7f 50 7f

    I guess something goes wrong with the getRange-start point. Anyone?
    Big thanks in advance!!

    • This topic was modified 3 months, 1 week ago by  EnzoF04.
    • This topic was modified 3 months, 1 week ago by  EnzoF04.
    #72727
    goodweather
    goodweather
    Participant

    Memory Block functions in Ctrlr:
    https://sourceforge.net/p/ctrlrv4/code/HEAD/tree/nightly/Source/Lua/JuceClasses/LMemoryBlock.cpp

    First look at the end of the file to find the list of the functions then scroll upwards to find the details of the function (for us, the list of arguments)
    You will see: getRange(start_position, number_of_bytes)

    #72733

    EnzoF04
    Participant

    Yes, I’m very sorry to spill time! I’m aware! and trail and error and using my mirror hall in my head, I got the way of working with the blocks and the getRange!

    I need to find a way of learning myself the art of creating functions. I’m aware of my repetition in my code. This will improve after a while.

    Many thanks for now, Goodweather! You’ve been kind and patient to get me on my way!

    #72736

    human fly
    Participant

    ‘the art of creating functions’ – yes: what i must do, still.
    i think that the basics are the most difficult part, from
    within Ctrlr – and that what you wanted to do, displaying
    the console output on the workspace, is a natural response.
    so i’m pleased you brought that up.

    lots of great info in the past few days.

    #72738
    goodweather
    goodweather
    Participant

    Writing functions is part of basic programming techniques. I would advise you to search for that on internet and to try to find some general article on that.

    The base philosophy is “as soon as something needs to be executed a few times it is better to write a function for it because the code exists only once and is thus much more maintainable”
    Once you decided to have your code only once in a function, you can make it flexible by passing one or more arguments to it. Depending on the argument values, the output of the function can vary because your function will contain some if…elseif…elseif statements.
    So, the function is doing the same thing but thanks to the arguments you can get a tailored output.

    The more you code, the more you read in forums, manuals, sites… the more you will understand and improve. just give time to time 😉

    #72740

    human fly
    Participant

    hehe well me very happy because i’ve just generated my
    first bulk file from panel values, and got it displaying
    where i want etc.(console and a label)

    (but WHY am i getting ‘FF’ entries?)

    my only current selfmade use of functions at this point,
    if i understand correctly, is having it pre-made and
    invoking it when i need it. still pretty basic stuff.
    hey but better than a couple of months ago lol.

    ok, so the FF was my deliberate invalid entries, i think,
    i needed to ‘void out’ a couple of wrong entries that were
    causing errors.

    #72741

    EnzoF04
    Participant

    cool, human, please post your code.. perhaps we can learn from it! Nice Job!

    #72743

    EnzoF04
    Participant

    About functions… I cam across this!

    http://lua-users.org/wiki/FunctionsTutorial
    and
    https://en.wikibooks.org/wiki/Lua_Programming/How_to_Lua/comment

    thanks, goodweather and human fly

    #72747

    human fly
    Participant

    great: back to fundamentals 😉
    (not sure abt the 2nd link tho’ …)

    iirc there were three good sites i liked, this was one of them.
    check my topic where i moan about having to learn Lua, it has
    a few useful links there lol

    #72748

    EnzoF04
    Participant

    The actual point is that i want to calculate how long the receiving message will be. I get some data from the device.

    a: Total words in sample. This is stored in a three byte part of the message. Let’s say it’s 360.
    b: The bits per word. This is stored in a single byte part of the message.
    c: The first 19 bytes part of the sysex message are parameters and sysex common and the last byte is the EOX.
    The remaining bytes are sample data blocks constructed of 1 byte for block number, 120 bytes of sample data and at the end of each block a checksum byte.

    See attached detailed info. I want to check if I’ve received the whole message with all the blocks of sample data. Is there a way of doing this?

    My thought was taking 360 (Total words in sample) – 20 (the 19 parameters and the EOX at the end) = 339 / 122

    	smpRcvBks = ((sMsg - 20)/122)
    	console ("sample blocks = "..2*smpRcvBks)
    	opSmpRcvBlk:getComponent():setPropertyString ("uiLabelText",tostring(smpRcvBks))
    

    but i never know if this is true because i count the getSize, the incoming message bytes instead of calculating from the data in the sample parameters.

    Attachments:
    You must be logged in to view attached files.
    #72755
    Possemo
    Possemo
    Participant

    Bits per word is always the same: 12. The S700 will accept other values but I would keep it simple and stay at 12 bits.

    When you know the total words in a complete transmission and you know that one block transmits 60 words (in 120 bytes) you can check if you got all words. Total words must be a multiple of 60 if I am not mistaken (if it fills the last one with zeroes).

    #72756

    EnzoF04
    Participant

    Ok, thanks Possemo, to recap: it should be something times 60 is total words or something less which is filled with zero’s? And as I was thinking total words divided by 60, is wrong.

    If, for example total words in sample is 360, this tells that I have six sample blocks. The bytes used to transmit these blocks are in total (6×120) 720 bytes. Each block has a byte for blocknumber and checksum (6 x 2 bytes) 12 bytes. Then there are bytes used for sample header and EOX 20 (19 bytes for the header and 1 for the EOX).

    This makes that I need to receive 752 bytes. If this is not true, I do not have received the complete sysex!

    Now I have it clear!! Thanks!!

    #72758
    goodweather
    goodweather
    Participant

    Hi again, thx for posting the doc of the S700.
    Here is the way you should do this upload (to combine with the other topic on sending the ACK at random…).

    – in MidiMessageReceived, you track for size=19
    – when a message of 19 bytes is received, you calculate the number of bytes (words) in your sample from bytes 9, 10 and 11.
    – when a message of 60 is received you append the data
    – when a message of 1 byte is received you chexk for F7 and/or number of blocks recieved

    if myMessage:getSize() == 19 then
    	mbHeader = myMessage:getData()
    	iNumBlocks = mbHeader:getByte(9) + 128*mbHeader:getByte(10)  + 16384*mbHeader:getByte(11) 
    	mbTemp=MemoryBlock()  -- will hold the sample data
    	iCounter = 0
    	-- send ACK
    elseif myMessage:getSize() == 60 then
    	iCounter = iCounter + 1
    	mbTemp:append(myMessage:getData():getRange(1,120))  -- append block of 120 bytes
    	-- send ACK
    elseif myMessage:getSize() == 1 then
    	if myMessage:getData():getByte(0) = 0xF7 then
    	-- you can check iCounter vs iNumBlocks
    	-- send ACK? Don't know if this is needed
    	-- here you call a method that will load your data into the modulators
    	LoadSampleData(mbTemp)
    	end
    end
    #72759
    Possemo
    Possemo
    Participant

    @goodweather – I agree to most of your code but two changes:

    iNumBlocks would be the total number of Words. So you will have to divide it by 60 to get the total amount of Blocks.

    The Block message size is 122, so instead of
    elseif myMessage:getSize() == 60 then
    I would do:
    elseif myMessage:getSize() == 122 then

    and I would include the Block Number and the Checksum. This may be a personal preference. You could omit these bytes, but you will need them when you send the dump back to the synth. so instead of
    mbTemp:append(myMessage:getData():getRange(1,120)) — append block of 120 bytes
    this:
    mbTemp:append(myMessage:getData():getRange(1,122)) — append block of 122 bytes

    #72760
    goodweather
    goodweather
    Participant

    Sorry about those errors, indeed!

    About the block number and checksum however, I’m not sure. It’s a question of way of working…
    I would prefer holding only the data and rebuilding the blocks as anyway you will have to recalculate the checksum. Somewhere, block number and checksum are not data.

    But as usual, there are different ways doing the same things 😉

    #72761

    EnzoF04
    Participant

    – in MidiMessageReceived, you track for size=19
    – when a message of 19 bytes is received, you calculate the number of bytes (words) in your sample from bytes 9, 10 and 11.
    – when a message of 60 is received you append the data
    – when a message of 1 byte is received you chexk for F7 and/or number of blocks recieved

    Thanks for the reply! The problem is that there is no EOX from the S700. I shoot a bunch of ACK’s to the S700 to make sure the S700 keeps on sending data. If not receiving the ACK by S700 it will send an EOX. I NEED to count incoming bytes or find an other way around this.

    The calculations are made clear by Possemo and Human Fly in the other topic!
    Thanks all, I cannot express my thanks to all of you, Human Fly, Possemo and Goodweather, via the forum.. We could take a beer some time?

    #72762

    human fly
    Participant

    a virtual beer !

    nothing to do with me: without goodweather and Possemo’s
    help i wouldn’t be able to do anything. i’m pretty blown
    away by the speed of their responses today and quite
    unable to follow that code -maybe if i look at it really
    hard for a really long time … and your project is not
    exactly a typical Ctrlr project either – i haven’t seen
    any posts here about dealing with sample dumps over MIDI.

    btw: is MIDI sample transfer as slow as i’ve always been
    led to believe? how fast/slow is this happening? ( i’ve
    been thinking of getting a volcaSample and quite like the
    idea of transfer by audio data ) – my rack sampler is
    an emu esi4000, which doesn’t handle sysex, unfortunately
    (for control/editing). one of the members here had a look
    into hacking into it without sysex but i don’t think it
    was feasible. i like it because it doesn’t stick out 45cm
    at the back 🙂 (and has loads of filters, but i think i
    prefer akai operating systems, which are a bit more
    intuitive to use. emu feels the wrong way round to me)

    #72763
    goodweather
    goodweather
    Participant

    Thx guys and no pbm at all. With pleasure!
    @Enzo: where are you living? I’m going to Nijmegen soon… I mean, for the beer 🙂

    About the EOX… what do you mean? Doesn’t Ctlr MidiMessageReceived capture automatically each part of the message?
    I mean, as I put in my code, you first get 19 bytes then you send the ACK (I don’t know what msg it is but you know) then you know how many blocks you will receive and you just check for reception of 122 bytes. When you get 122 bytes, you store the data and send your ACK to get the next block… until end.
    Or is it something I didn’t understand? Isn’t the S700 sending by block of 122 bytes and waiting for ACK after each block to send the next one?

    #72854

    EnzoF04
    Participant

    Just a quick ‘update’ to keep you informed.. was on holidays… will pick it up shortly!

    #72855
    Possemo
    Possemo
    Participant

    @goodweather: no this does not work on the S700. I forgot it too. The S700 does not send a sysex-end (F7) at the in-between messages. This makes it impossible to capture these parts separately. Ctrlr will wait for an F7. Before F7 it won’t do anything. That’s why you have to send the ACK’s blindly.

Viewing 20 posts - 1 through 20 (of 20 total)

You must be logged in to reply to this topic.

Comments are closed.