upload
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
このリポジトリはアーカイブされています。 ファイルの閲覧とクローンは可能ですが、プッシュや、課題・プルリクエストのオープンはできません。

sysex_tools.c 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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)
  67. return 0;
  68. //fill out the fully encoded sections
  69. for(i = 0; i < decoded_full; i++) {
  70. uint16_t encoded_msb_idx = i * 8;
  71. uint16_t output_start_index = i * 7;
  72. for(j = 0; j < 7; j++){
  73. decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1];
  74. decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j)));
  75. }
  76. }
  77. uint8_t remainder = length % 8;
  78. if (remainder) {
  79. uint16_t encoded_msb_idx = decoded_full * 8;
  80. uint16_t output_start_index = decoded_full * 7;
  81. for(j = 0; j < (remainder - 1); j++) {
  82. decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1];
  83. decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j)));
  84. }
  85. return decoded_full * 7 + remainder - 1;
  86. } else {
  87. return decoded_full * 7;
  88. }
  89. }