X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fevoral%2Fevoral%2Fmidi_util.h;h=2ad5b3f3288ad8b6f23d25432b54d88b33bf091a;hb=196e910992659ea062da45499c1ac5906a0fa6c4;hp=2193e4c4b199ff8731947764a0213601967607f6;hpb=b6daa2d643c5cf4d07ae53b7e347b03e1bc145de;p=ardour.git diff --git a/libs/evoral/evoral/midi_util.h b/libs/evoral/evoral/midi_util.h index 2193e4c4b1..2ad5b3f328 100644 --- a/libs/evoral/evoral/midi_util.h +++ b/libs/evoral/evoral/midi_util.h @@ -1,16 +1,16 @@ /* This file is part of Evoral. - * Copyright(C) 2008 Dave Robillard + * Copyright(C) 2008 David Robillard * Copyright(C) 2000-2008 Paul Davis - * + * * Evoral 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 2 of the License, or(at your option) any later * version. - * + * * Evoral 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 details. - * + * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA @@ -19,17 +19,24 @@ #ifndef EVORAL_MIDI_UTIL_H #define EVORAL_MIDI_UTIL_H +#include + +#include +#include +#include #include +#include "evoral/visibility.h" #include "evoral/midi_events.h" namespace Evoral { + /** Return the size of the given event including the status byte, - * or -1 if unknown (eg sysex) + * or -1 if unknown (e.g. sysex) */ static inline int -midi_event_size(unsigned char status) +midi_event_size(uint8_t status) { // if we have a channel event if (status >= 0x80 && status < 0xF0) { @@ -60,31 +67,38 @@ midi_event_size(unsigned char status) case MIDI_CMD_COMMON_SENSING: case MIDI_CMD_COMMON_RESET: return 1; - + case MIDI_CMD_COMMON_SYSEX: + std::cerr << "event size called for sysex\n"; return -1; } + std::cerr << "event size called for unknown status byte " << std::hex << (int) status << "\n"; return -1; } -/** Return the size of the given event including the status byte - * (which must be the first byte in \a buffer), - * or -1 if unknown (eg sysex) +/** Return the size of the given event including the status byte, + * or -1 if event is illegal. */ static inline int -midi_event_size(uint8_t* buffer) +midi_event_size(const uint8_t* buffer) { uint8_t status = buffer[0]; - - // if we have a channel event + + // Mask off channel if applicable if (status >= 0x80 && status < 0xF0) { - status &= 0xF0; // mask off the channel + status &= 0xF0; } - + + // see http://www.midi.org/techspecs/midimessages.php if (status == MIDI_CMD_COMMON_SYSEX) { int end; - for (end = 1; buffer[end] != MIDI_CMD_COMMON_SYSEX_END; end++); + + for (end = 1; buffer[end] != MIDI_CMD_COMMON_SYSEX_END; end++) { + if ((buffer[end] & 0x80) != 0) { + return -1; + } + } assert(buffer[end] == MIDI_CMD_COMMON_SYSEX_END); return end + 1; } else { @@ -92,6 +106,35 @@ midi_event_size(uint8_t* buffer) } } +/** Return true iff the given buffer is a valid MIDI event. + * \a len must be exactly correct for the contents of \a buffer + */ +static inline bool +midi_event_is_valid(const uint8_t* buffer, size_t len) +{ + uint8_t status = buffer[0]; + if (status < 0x80) { + return false; + } + const int size = midi_event_size(buffer); + if (size < 0 || (size_t)size != len) { + return false; + } + if (status < 0xf0) { + /* Channel messages: all start with status byte followed by + * non status bytes. + */ + for (size_t i = 1; i < len; ++i) { + if ((buffer[i] & 0x80) != 0) { + return false; // Non-status byte has MSb set + } + } + } + return true; +} + +LIBEVORAL_API std::string midi_note_name (uint8_t noteval); + } // namespace Evoral #endif // EVORAL_MIDI_UTIL_H