sysex_tools.c 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // midi for embedded chips,
  2. // Copyright 2010 Alex Norman
  3. //
  4. // This file is part of avr-midi.
  5. //
  6. // avr-midi is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. //(at your option) any later version.
  10. //
  11. // avr-midi is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
  18. #include "sysex_tools.h"
  19. uint16_t sysex_encoded_length(uint16_t decoded_length) {
  20. uint8_t remainder = decoded_length % 7;
  21. if (remainder)
  22. return (decoded_length / 7) * 8 + remainder + 1;
  23. else
  24. return (decoded_length / 7) * 8;
  25. }
  26. uint16_t sysex_decoded_length(uint16_t encoded_length) {
  27. uint8_t remainder = encoded_length % 8;
  28. if (remainder)
  29. return (encoded_length / 8) * 7 + remainder - 1;
  30. else
  31. return (encoded_length / 8) * 7;
  32. }
  33. uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, const uint16_t length) {
  34. uint16_t encoded_full = length / 7; // number of full 8 byte sections from 7 bytes of input
  35. uint16_t i, j;
  36. // fill out the fully encoded sections
  37. for (i = 0; i < encoded_full; i++) {
  38. uint16_t encoded_msb_idx = i * 8;
  39. uint16_t input_start_idx = i * 7;
  40. encoded[encoded_msb_idx] = 0;
  41. for (j = 0; j < 7; j++) {
  42. uint8_t current = source[input_start_idx + j];
  43. encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j);
  44. encoded[encoded_msb_idx + 1 + j] = 0x7F & current;
  45. }
  46. }
  47. // fill out the rest if there is any more
  48. uint8_t remainder = length % 7;
  49. if (remainder) {
  50. uint16_t encoded_msb_idx = encoded_full * 8;
  51. uint16_t input_start_idx = encoded_full * 7;
  52. encoded[encoded_msb_idx] = 0;
  53. for (j = 0; j < remainder; j++) {
  54. uint8_t current = source[input_start_idx + j];
  55. encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j);
  56. encoded[encoded_msb_idx + 1 + j] = 0x7F & current;
  57. }
  58. return encoded_msb_idx + remainder + 1;
  59. } else {
  60. return encoded_full * 8;
  61. }
  62. }
  63. uint16_t sysex_decode(uint8_t *decoded, const uint8_t *source, const uint16_t length) {
  64. uint16_t decoded_full = length / 8;
  65. uint16_t i, j;
  66. if (length < 2) return 0;
  67. // fill out the fully encoded sections
  68. for (i = 0; i < decoded_full; i++) {
  69. uint16_t encoded_msb_idx = i * 8;
  70. uint16_t output_start_index = i * 7;
  71. for (j = 0; j < 7; j++) {
  72. decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1];
  73. decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j)));
  74. }
  75. }
  76. uint8_t remainder = length % 8;
  77. if (remainder) {
  78. uint16_t encoded_msb_idx = decoded_full * 8;
  79. uint16_t output_start_index = decoded_full * 7;
  80. for (j = 0; j < (remainder - 1); j++) {
  81. decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1];
  82. decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j)));
  83. }
  84. return decoded_full * 7 + remainder - 1;
  85. } else {
  86. return decoded_full * 7;
  87. }
  88. }