88 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Markdown
		
	
	
	
| # SysEx Encoding & Decoding
 | |
| 
 | |
| There are various ways of encoding & decoding arbitrary 8-bit wide data into
 | |
| SysEx, which is 7-bit wide.
 | |
| 
 | |
| The [official documentation](http://www.somascape.org/midi/tech/spec.html#nusx_fd)
 | |
| for FileDump data exchanges states the following:
 | |
| 
 | |
|   > The 8-bit file data needs to be converted to 7-bit form,
 | |
|   > with the result that every 7 bytes of file data translates
 | |
|   > to 8 bytes in the MIDI stream.
 | |
|   >
 | |
|   > For each group of 7 bytes (of file data) the top bit from each
 | |
|   > is used to construct an eigth byte, which is sent first.
 | |
|   > So:
 | |
|   > ```
 | |
|   >   AAAAaaaa BBBBbbbb CCCCcccc DDDDdddd EEEEeeee FFFFffff GGGGgggg
 | |
|   > ```
 | |
|   > becomes:
 | |
|   > ```
 | |
|   >   0ABCDEFG 0AAAaaaa 0BBBbbbb 0CCCcccc 0DDDdddd 0EEEeeee 0FFFffff 0GGGgggg
 | |
|   > ```
 | |
|   >
 | |
|   > The final group may have less than 7 bytes, and is coded as follows
 | |
|   > (e.g. with 3 bytes in the final group):
 | |
|   > ```
 | |
|   >   0ABC0000 0AAAaaaa 0BBBbbbb 0CCCcccc
 | |
|   > ```
 | |
| 
 | |
| ## SysEx encoding / decoding functions
 | |
| 
 | |
| The MIDI library supplies two functions to do this, `encodeSysEx` and `decodeSysEx`.
 | |
| 
 | |
| Example usage:
 | |
| ```c++
 | |
| #include <MIDI.h>
 | |
| 
 | |
| static const byte myData[12] = {
 | |
|     // Hex dump: CAFEBABE BAADF00D FACADE42
 | |
|     0xca, 0xfe, 0xba, 0xbe, 0xba, 0xad, 0xf0, 0x0d,
 | |
|     0xfa, 0xca, 0xde, 0x42
 | |
| };
 | |
| 
 | |
| byte encoded[16];
 | |
| const unsigned encodedSize = midi::encodeSysEx(myData, encoded, 12);
 | |
| // Encoded hex dump: 07 4a 7e 3a 3e 3a 2d 70 07 0d 7a 4a 5e 42
 | |
| 
 | |
| byte decoded[12];
 | |
| const unsigned decoded = midi::decodeSysEx(encoded, decoded, encodedSize);
 | |
| ```
 | |
| 
 | |
| ## Special case for Korg devices
 | |
| 
 | |
| Korg apparently uses another convention for their SysEx encoding / decoding,
 | |
| where:
 | |
| ```
 | |
| AAAAaaaa BBBBbbbb CCCCcccc DDDDdddd EEEEeeee FFFFffff GGGGgggg
 | |
| ```
 | |
| becomes:
 | |
| ```
 | |
| 0GFEDCBA 0AAAaaaa 0BBBbbbb 0CCCcccc 0DDDdddd 0EEEeeee 0FFFffff 0GGGgggg
 | |
| ```
 | |
| 
 | |
| The order of the bits in the "header" byte is reversed.
 | |
| To follow this beheaviour, set the inFlipHeaderBits argument to true.
 | |
| 
 | |
| Example:
 | |
| ```c++
 | |
| void handleSysEx(byte* inData, unsigned inSize)
 | |
| {
 | |
|     // SysEx body data starts at 3rd byte: F0 42 aa bb cc dd F7
 | |
|     // 42 being the hex value of the Korg SysEx ID.
 | |
|     const unsigned dataStartOffset   = 2;
 | |
|     const unsigned encodedDataLength = inSize - 3; // Remove F0 42 & F7
 | |
| 
 | |
|     // Create a large enough buffer where to decode the message
 | |
|     byte decodedData[64];
 | |
| 
 | |
|     const unsigned decodedSize = decodeSysEx(inData + dataStartOffset,
 | |
|                                              decodedData,
 | |
|                                              encodedDataLength,
 | |
|                                              true); // flip header bits
 | |
|     // Do stuff with your message
 | |
| }
 | |
| ```
 | |
| 
 | |
| See original discussion in issue [#92](FortySevenEffects/arduino_midi_library#92).
 |