Ardour  9.0-pre0-582-g084a23a80d
libs/evoral/evoral/midi_util.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2014 David Robillard <d@drobilla.net>
3  * Copyright (C) 2009-2014 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2009 Hans Baier <hansfbaier@googlemail.com>
5  * Copyright (C) 2013 John Emmas <john@creativepost.co.uk>
6  * Copyright (C) 2015-2016 Robin Gareus <robin@gareus.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #ifndef EVORAL_MIDI_UTIL_H
24 #define EVORAL_MIDI_UTIL_H
25 
26 #include <iostream>
27 
28 #include <stdint.h>
29 #include <string>
30 #include <sys/types.h>
31 #include <assert.h>
32 
33 #include "evoral/visibility.h"
34 #include "evoral/midi_events.h"
35 
36 namespace Evoral {
37 
38 
42 static inline int
43 midi_event_size(uint8_t status)
44 {
45  // if we have a channel event
46  if (status >= 0x80 && status < 0xF0) {
47  status &= 0xF0; // mask off the channel
48  }
49 
50  switch (status) {
51  case MIDI_CMD_NOTE_OFF:
52  case MIDI_CMD_NOTE_ON:
54  case MIDI_CMD_CONTROL:
55  case MIDI_CMD_BENDER:
57  return 3;
58 
63  return 2;
64 
73  return 1;
74 
76  std::cerr << "event size called for sysex\n";
77  return -1;
78  }
79 
80  std::cerr << "event size called for unknown status byte " << std::hex << (int) status << "\n";
81  return -1;
82 }
83 
87 static inline int
88 midi_event_size(const uint8_t* buffer)
89 {
90  uint8_t status = buffer[0];
91 
92  // Mask off channel if applicable
93  if (status >= 0x80 && status < 0xF0) {
94  status &= 0xF0;
95  }
96 
97  // see http://www.midi.org/techspecs/midimessages.php
98  if (status == MIDI_CMD_COMMON_SYSEX) {
99  int end;
100 
101  for (end = 1; buffer[end] != MIDI_CMD_COMMON_SYSEX_END; end++) {
102  if ((buffer[end] & 0x80) != 0) {
103  return -1;
104  }
105  }
106  assert(buffer[end] == MIDI_CMD_COMMON_SYSEX_END);
107  return end + 1;
108  } else {
109  return midi_event_size(status);
110  }
111 }
112 
116 static inline bool
117 midi_event_is_valid(const uint8_t* buffer, size_t len)
118 {
119  uint8_t status = buffer[0];
120  if (status < 0x80) {
121  return false;
122  }
123  const int size = midi_event_size(buffer);
124  if (size < 0 || (size_t)size != len) {
125  return false;
126  }
127  if (status < 0xf0) {
128  /* Channel messages: all start with status byte followed by
129  * non status bytes.
130  */
131  for (size_t i = 1; i < len; ++i) {
132  if ((buffer[i] & 0x80) != 0) {
133  return false; // Non-status byte has MSb set
134  }
135  }
136  }
137  return true;
138 }
139 
140 } // namespace Evoral
141 
142 #endif // EVORAL_MIDI_UTIL_H
143 
#define MIDI_CMD_NOTE_PRESSURE
Definition: midi_events.h:108
#define MIDI_CMD_COMMON_CONTINUE
Definition: midi_events.h:122
#define MIDI_CMD_COMMON_SYSEX_END
Definition: midi_events.h:118
#define MIDI_CMD_COMMON_STOP
Definition: midi_events.h:123
#define MIDI_CMD_COMMON_CLOCK
Definition: midi_events.h:119
#define MIDI_CMD_COMMON_SONG_SELECT
Definition: midi_events.h:116
#define MIDI_CMD_NOTE_ON
Definition: midi_events.h:107
#define MIDI_CMD_BENDER
Definition: midi_events.h:112
#define MIDI_CMD_COMMON_MTC_QUARTER
Definition: midi_events.h:114
#define MIDI_CMD_COMMON_SENSING
Definition: midi_events.h:124
#define MIDI_CMD_COMMON_SYSEX
Definition: midi_events.h:113
#define MIDI_CMD_PGM_CHANGE
Definition: midi_events.h:110
#define MIDI_CMD_COMMON_RESET
Definition: midi_events.h:125
#define MIDI_CMD_CONTROL
Definition: midi_events.h:109
#define MIDI_CMD_COMMON_START
Definition: midi_events.h:121
#define MIDI_CMD_COMMON_TUNE_REQUEST
Definition: midi_events.h:117
#define MIDI_CMD_COMMON_SONG_POS
Definition: midi_events.h:115
#define MIDI_CMD_CHANNEL_PRESSURE
Definition: midi_events.h:111
#define MIDI_CMD_NOTE_OFF
Definition: midi_events.h:106
Definition: editor.h:86
static bool midi_event_is_valid(const uint8_t *buffer, size_t len)
static int midi_event_size(uint8_t status)