diff options
Diffstat (limited to 'protocol/lufa/midi/sysex_tools.c')
| -rwxr-xr-x | protocol/lufa/midi/sysex_tools.c | 99 | 
1 files changed, 99 insertions, 0 deletions
| diff --git a/protocol/lufa/midi/sysex_tools.c b/protocol/lufa/midi/sysex_tools.c new file mode 100755 index 0000000000..7563a3e2aa --- /dev/null +++ b/protocol/lufa/midi/sysex_tools.c @@ -0,0 +1,99 @@ +//midi for embedded chips, +//Copyright 2010 Alex Norman +// +//This file is part of avr-midi. +// +//avr-midi is free software: you can redistribute it and/or modify +//it under the terms of the GNU General Public License as published by +//the Free Software Foundation, either version 3 of the License, or +//(at your option) any later version. +// +//avr-midi is distributed in the hope that it will be useful, +//but WITHOUT ANY WARRANTY; without even the implied warranty of +//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +//GNU General Public License for more details. +// +//You should have received a copy of the GNU General Public License +//along with avr-midi.  If not, see <http://www.gnu.org/licenses/>. + +#include "sysex_tools.h" + +uint16_t sysex_encoded_length(uint16_t decoded_length){ +   uint8_t remainder = decoded_length % 7; +   if (remainder) +      return (decoded_length / 7) * 8 + remainder + 1; +   else +      return (decoded_length / 7) * 8; +} + +uint16_t sysex_decoded_length(uint16_t encoded_length){ +   uint8_t remainder = encoded_length % 8; +   if (remainder) +      return (encoded_length / 8) * 7 + remainder - 1; +   else +      return (encoded_length / 8) * 7; +} + +uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, const uint16_t length){ +   uint16_t encoded_full = length / 7; //number of full 8 byte sections from 7 bytes of input +   uint16_t i,j; + +   //fill out the fully encoded sections +   for(i = 0; i < encoded_full; i++) { +      uint16_t encoded_msb_idx = i * 8; +      uint16_t input_start_idx = i * 7; +      encoded[encoded_msb_idx] = 0; +      for(j = 0; j < 7; j++){ +         uint8_t current = source[input_start_idx + j]; +         encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j); +         encoded[encoded_msb_idx + 1 + j] = 0x7F & current; +      } +   } + +   //fill out the rest if there is any more +   uint8_t remainder = length % 7; +   if (remainder) { +      uint16_t encoded_msb_idx = encoded_full * 8; +      uint16_t input_start_idx = encoded_full * 7; +      encoded[encoded_msb_idx] = 0; +      for(j = 0; j < remainder; j++){ +         uint8_t current = source[input_start_idx + j]; +         encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j); +         encoded[encoded_msb_idx + 1 + j] = 0x7F & current; +      } +      return encoded_msb_idx + remainder + 1; +   } else { +      return encoded_full * 8; +   } +} + +uint16_t sysex_decode(uint8_t *decoded, const uint8_t *source, const uint16_t length){ +   uint16_t decoded_full = length / 8; +   uint16_t i,j; + +   if (length < 2) +      return 0; + +   //fill out the fully encoded sections +   for(i = 0; i < decoded_full; i++) { +      uint16_t encoded_msb_idx = i * 8; +      uint16_t output_start_index = i * 7; +      for(j = 0; j < 7; j++){ +         decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1]; +         decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j))); +      } +   } +   uint8_t remainder = length % 8; +   if (remainder) { +      uint16_t encoded_msb_idx = decoded_full * 8; +      uint16_t output_start_index = decoded_full * 7; +      for(j = 0; j < (remainder - 1); j++) { +         decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1]; +         decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j))); +      } +      return decoded_full * 7 + remainder - 1; +   } else { +      return decoded_full * 7; +   } +} + | 
