Home › Forums › General › Programming › getSize only looking at last byte number
- This topic has 40 replies, 6 voices, and was last updated 3 years, 7 months ago by EnzoF04.
-
AuthorPosts
-
April 2, 2020 at 9:10 pm #117636
Here is the way you should do this upload
Dear @goodweather, this is not working for now. Can we think of a way to evaluate the (amount of) incoming bytes in real time? When I don’t send an ACK message to the S700, the S700 terminates with a f7 (EOX). So waiting with ‘midi message received’ is not they way to go. Randomly shooting ACK messages is not a decent way. I’ve seen the ‘ignore realtime MIDI messages on input’. Would this be an option? Tried to enable but no difference.
This is what you suggested a few years ago:
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
I’ve attached my version as it is. Hopefully I can get progress.
Attachments:
You must be logged in to view attached files.September 7, 2020 at 7:14 am #119691Hello, I’ve been watching this thread for some time now, and wondering how things have progressed, very interested in seeing how it’s going. Cheers
September 7, 2020 at 12:02 pm #119693Hi SymphonicSamples,
Well I’ve done some things with CTRLR for a SixTrak synth. But besides that, this is still at the same point. The problem is that I am not able to respond back to the sampler while sampler is sending sysex. As far as I know (been told) is that CTRLR is storing incoming sysex data and passes it on to next code and routines when CTRLR thinks it is complete or the synth / sampler has finished sending. BUT the early Akai samplers want receiving equippement to respond during the sending of their messages as: sending part A, expecting a receive part A OK, sending part B, expecting an receive part B OK, sending part C, expecting a receive part C OK and so on.
But if the Akai is not receiving this receive part A OK message back, it terminates the sending of the data.
So if someone can help me with this, it would be a good push into the right direction.
September 7, 2020 at 9:01 pm #119699Hello all, maybe time to come back on this tricky one 🙂
I didn’t remember Possemo’s answer that the S700 doesn’t send a complete message and expects some regular ACK before sending an F7.
Different things coming to my mind:
1/ test what MidiMessageReceived is doing. Does it accept all kinds of messages or must all messages ends with F7
2/ if it accepts all messages then we could do something like
– create a memoryblock outside MidiMessageReceived : mbMessage = MemoryBlock()
– in MidiMessageReceived, append message to memory block; check if message contains F7; if yes then call method to process the memory block; if not send ACK
3/ create a timer that will send ACK every x ms (100ms?) In MidiMessageReceived, you append to the memoryblock until you get some F7 then you stop the timer and process the messageNot possible to test this without an S700 I’m afraid…
Don’t forget to use the Midi monitor to see what you are getting and sending!
September 7, 2020 at 10:51 pm #119700Hi all,
This way of exchanging data has a name: it is the handshake transfer procedure, also used by Roland in some older samplers and synths.
It was used for handling large amounts of data-sampler waveforms and synthesizer tones over the entire range as it was considered more efficient than one-way transfer.Types of messages:
-want to send data: WSD (40H)
-request data: RQD (41H)
-data set: DAT (42H)
-acknowledge: ACK (43H)
-end of data: EOD (45H)
-communication error: ERR (4EH)
-rejection: RJC (4FH)Concerning the ACK: this message is sent out when no error was detected on reception of a WSD, DAT, EOD. Unless it receives an ACK message, the device at the other end will not proceed to the next operation.
Concerning the EOD: this message is sent out to inform a remote device of the end of a message. Communication, however, will not come to an end unless the remote device returns an ACK message even though an EOD message was transmitted.
ERR warns the remote device of a communications fault encountered during message transmission due, for example, to a checksum error. An ERR message may be send out by a device on either side of the interface.
When it receives an ERR message, the sending device may either attempt to send out the last message a second time or terminate the communication by sending out an RJC.RJC is sent out when there is a need to terminate the communication. An RJC will be triggered when
-a WSD or RQD message has specified an illegal data address or size
-the device is not ready for communication
-an illegal number of adresses or data has been detected
-data transfer has been terminated by an operator
-a communications error has occurredSeptember 7, 2020 at 11:06 pm #119701So, requesting data:
RQD ----------> <----------DAT ACK ----------> <----------DAT ACK -----------> - - <----------EOD ACK ----------->
Sending data:
WSD ----------> <----------ACK DAT ----------> <----------ACK DAT ----------> <----------ACK - - EOD -----------> <-----------ACK
September 7, 2020 at 11:16 pm #119703So, after sending a RQD or WSD or EOD, you have to make some lua code to catch the ACK, ERR, DAT or RJC and to respond on each of them in an appropriate manner.
Thomas
September 8, 2020 at 12:57 am #119704Yes GoodWeather, this is what I did. With the timer you mentioned. This was a really bumpy road to go. The timing is not accurate. So the change of ending or breaking up transmit before all data blocks are sent is pretty big. All can be checked because the size of the data requested can be requested from the sampler. All midi data blocks have their own checksum which can be calculated so everything is verifiable. But first I need to process the sysex while it is incoming (real time) and respond to this with appropriate messages.
I don’t have the time to dive into this at this moment but will plan to pick it up when decent ideas about processing the real time sysex are clear to me. Any ideas are welcome.
September 8, 2020 at 1:01 am #119705it is the handshake transfer procedure
I am aware of this, yes and I’ve got the documentation on the sysex implementation of the S700 (and S612) so I know how to communicate. But the problem is that CTRLR is forwarding the sysex after the closing byte is received. CTRLR does not allow to establish and maintain the ‘open communication’. (As far as I know).
September 8, 2020 at 9:46 am #119708goodweather wrote:
in MidiMessageReceived, append message to memory block; check if message contains F7; if yes then call method to process the memory block; if not send ACK
A good procedure. but in my opinion you have to check not for F7 but for EOD (45H –>end of data) in a separate message. The communication stays open until the ACK is sent out responding to the EOD.
Sending arbitrary ACK messages may confuse the handshake procedure and disrupt communication.
- This reply was modified 3 years, 7 months ago by samoht.
September 8, 2020 at 10:27 am #119710I’ve not tried out what follows, it is a try to figure out a working procedure.
So, a data set can be identified when you know the position of 42H (Data set DAT) in every data set:
midiMessageReceived = function(midi) local idDAT = midi:getLuaData():getByte(5) -- dupposing byte 5 is 42H -->DAT if IdDAT == 0x42 then -- DAT Identification byte Dat = midi:getData()
What I don’t know is how you can differentiate between different chunks of data.
Therefore, after appending the already received DAT to a memory block outside midiMessageReceived as goodweather suggested, this already received block must disappear in the midi buffer. (In docs.juce.com/master/classMidiBuffer.html are methods to do this).Thereafter an ACK can be send and the second DAT can be recognized in the same manner.
So on until the remote machine sends an EOD.
This message can be recognized when you know the exact length of this message and/or the exact location of 45H in this message. A final ACK brings the communication to an end.All this steps can be done in one lua function
Cheers,
Thomas- This reply was modified 3 years, 7 months ago by samoht.
September 8, 2020 at 11:34 am #119713The communication stays open until the ACK is sent out responding to the EOD.
This is not the case; Akai terminates communication within tenths of seconds if ACK not received. This is very time critical. But as I read, there are coming good ideas to work.
This message can be recognized when you know the exact length of this message and/or the exact location of 45H in this message.
You mean in the complete sysex (all chunks of data messages) or in this specific chunk? Everything can be calculated from the message CTRLR can receive when asked for sample information, as I can remember.
So prior request for a sample, CTRLR needs to ask what the sample consists of (how many words, sample rate, sample length, sample parameters). Akai works with checksums and the received sample parameters make receiving sample data very predictable. (But my programming qualities lack knowledge.)
I’m very excited you’ve picked this up Thomas @samoht, @Goodweather and @Symphonicsamples
I still believe in success in this project.September 8, 2020 at 4:09 pm #119715I’ve found the Akai S700 midi implementation.
The handshaking procedure is not exactly, but fundamentally identic with the Roland procedure.
RSD -----> (request send data) <-----data (first of 546 blocks of data, all with 0x40 as 2nd byte, each with its own 1st byte) ACKS -----> (FO 7E 7F F7) <-----data (all 546 data blocks have the same length, I think 60 byte chunks) ACKS -----> <------EOX (F7)
- This reply was modified 3 years, 7 months ago by samoht.
September 9, 2020 at 10:23 am #119721Can you post the link to the S700 midi implementation so I can have a look?
If there is some pattern in the exchange then it can be coded easily like:
– button to request load. Initialize MB. counter=0
– MidiMessageReceived: check received message, if byte(1)=0x40 then append to MB; send ACK; counter =1
else if size=60 then append to MB, send ACK; counter = counter+1
else if byte(0)=0xF7 then append to MB; display MB or do whatever with the dataSo, forget about my proposal to use a timer to send ACK (didn’t know it would interfere); we control it based on what we are receiving.
September 9, 2020 at 10:50 am #119724Hi goodweather,
file:///media/fuse/drivefs-ba7299c55cd588fe9c050512a5947586/root/AkaiS700_MIDI_Implementation_V1.0.pdf
Regards,
ThomasSeptember 9, 2020 at 11:07 am #119725Hi goodweather,
Addendum:
For the complete manual with standard one page midi implementation chart at the end:https://www.polynominal.com/akai-s700/assets/files/akai-s700-manual.pdf
Thomas
September 9, 2020 at 2:49 pm #119726Thx Thomas but the link to the Midi implementation is not working.
Nice pseudo 😉
/DominiqueSeptember 9, 2020 at 2:54 pm #119727hopefully this works
Attachments:
You must be logged in to view attached files.September 9, 2020 at 6:00 pm #119729Hi,
Some additional information:
In the midi implementation doc (very well set by Enzo) “closed loop transmission” is mentioned. What “handshaking procedure” is for Roland is “closed loop transmission” in the sample dump standard (SDS).
SDS is a standardized protocol. For more info on SDS see:http://www.4front-tech.com/pguide/midi/midi8.html
I want to draw attention to this sentence in the S700 doc: “A further enhancement of the standard sample dump protocol is that when closed loop transmission is used, gaps between blocks may be as long as 10 seconds rather than the 20mS specified.”
September 9, 2020 at 7:50 pm #119732Hi all,
Some more additional info on SDS protocol that may be of interest:
When a sample transfer contains more than 128 data blocks (0-> 127), the number of the following block is set to 0 and so on like a three digit odometer jumping from 999 to 000.
This may help with identification of the data blocks.
-
AuthorPosts
- The forum ‘Programming’ is closed to new topics and replies.