diff options
Diffstat (limited to 'quantum/api/api_sysex.c')
| -rw-r--r-- | quantum/api/api_sysex.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/quantum/api/api_sysex.c b/quantum/api/api_sysex.c index a4a554e76..868f854b9 100644 --- a/quantum/api/api_sysex.c +++ b/quantum/api/api_sysex.c | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | #include "api_sysex.h" | 1 | #include "api_sysex.h" |
| 2 | #include "sysex_tools.h" | ||
| 3 | #include "print.h" | ||
| 2 | 4 | ||
| 3 | void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) { | 5 | void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) { |
| 4 | // SEND_STRING("\nTX: "); | 6 | // SEND_STRING("\nTX: "); |
| @@ -6,24 +8,50 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, | |||
| 6 | // send_byte(bytes[i]); | 8 | // send_byte(bytes[i]); |
| 7 | // SEND_STRING(" "); | 9 | // SEND_STRING(" "); |
| 8 | // } | 10 | // } |
| 9 | uint8_t * precode = malloc(sizeof(uint8_t) * (length + 2)); | 11 | if (length > API_SYSEX_MAX_SIZE) { |
| 10 | precode[0] = message_type; | 12 | xprintf("Sysex msg too big %d %d %d", message_type, data_type, length); |
| 11 | precode[1] = data_type; | 13 | return; |
| 12 | memcpy(precode + 2, bytes, length); | 14 | } |
| 13 | uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 2))); | 15 | |
| 14 | uint16_t encoded_length = sysex_encode(encoded, precode, length + 2); | 16 | |
| 15 | uint8_t * array = malloc(sizeof(uint8_t) * (encoded_length + 5)); | 17 | // The buffer size required is calculated as the following |
| 16 | array[0] = 0xF0; | 18 | // API_SYSEX_MAX_SIZE is the maximum length |
| 17 | array[1] = 0x00; | 19 | // In addition to that we have a two byte message header consisting of the message_type and data_type |
| 18 | array[2] = 0x00; | 20 | // This has to be encoded with an additional overhead of one byte for every starting 7 bytes |
| 19 | array[3] = 0x00; | 21 | // We just add one extra byte in case it's not divisible by 7 |
| 20 | array[encoded_length + 4] = 0xF7; | 22 | // Then we have an unencoded header consisting of 4 bytes |
| 21 | memcpy(array + 4, encoded, encoded_length); | 23 | // Plus a one byte terminator |
| 22 | midi_send_array(&midi_device, encoded_length + 5, array); | 24 | const unsigned message_header = 2; |
| 25 | const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header; | ||
| 26 | const unsigned encoding_overhead = unencoded_message / 7 + 1; | ||
| 27 | const unsigned encoded_size = unencoded_message + encoding_overhead; | ||
| 28 | const unsigned unencoded_header = 4; | ||
| 29 | const unsigned terminator = 1; | ||
| 30 | const unsigned buffer_size = encoded_size + unencoded_header + terminator; | ||
| 31 | uint8_t buffer[encoded_size + unencoded_header + terminator]; | ||
| 32 | // The unencoded header | ||
| 33 | buffer[0] = 0xF0; | ||
| 34 | buffer[1] = 0x00; | ||
| 35 | buffer[2] = 0x00; | ||
| 36 | buffer[3] = 0x00; | ||
| 37 | |||
| 38 | // We copy the message to the end of the array, this way we can do an inplace encoding, using the same | ||
| 39 | // buffer for both input and output | ||
| 40 | const unsigned message_size = length + message_header; | ||
| 41 | uint8_t* unencoded_start = buffer + buffer_size - message_size; | ||
| 42 | uint8_t* ptr = unencoded_start; | ||
| 43 | *(ptr++) = message_type; | ||
| 44 | *(ptr++) = data_type; | ||
| 45 | memcpy(ptr, bytes, length); | ||
| 46 | |||
| 47 | unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size); | ||
| 48 | unsigned final_size = unencoded_header + encoded_length + terminator; | ||
| 49 | buffer[final_size - 1] = 0xF7; | ||
| 50 | midi_send_array(&midi_device, final_size, buffer); | ||
| 23 | 51 | ||
| 24 | // SEND_STRING("\nTD: "); | 52 | // SEND_STRING("\nTD: "); |
| 25 | // for (uint8_t i = 0; i < encoded_length + 5; i++) { | 53 | // for (uint8_t i = 0; i < encoded_length + 5; i++) { |
| 26 | // send_byte(array[i]); | 54 | // send_byte(buffer[i]); |
| 27 | // SEND_STRING(" "); | 55 | // SEND_STRING(" "); |
| 28 | // } | 56 | // } |
| 29 | } \ No newline at end of file | 57 | } |
