Ardour  9.0-pre0-582-g084a23a80d
Event.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2016 David Robillard <d@drobilla.net>
3  * Copyright (C) 2009-2013 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2009 Hans Baier <hansfbaier@googlemail.com>
5  * Copyright (C) 2010 Carl Hetherington <carl@carlh.net>
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_EVENT_HPP
24 #define EVORAL_EVENT_HPP
25 
26 #include <algorithm>
27 #include <cstdlib>
28 #include <cstring>
29 #include <cmath>
30 #include <sstream>
31 #include <stdint.h>
32 
33 #include "evoral/midi_events.h"
34 #include "evoral/types.h"
35 #include "evoral/visibility.h"
36 
41 #define EVORAL_EVENT_ALLOC 1
42 
43 namespace Evoral {
44 
48 
53 template<typename Time>
55 public:
56 #ifdef EVORAL_EVENT_ALLOC
57  Event(EventType type=NO_EVENT, Time time=Time(), uint32_t size=0, uint8_t* buf=NULL, bool alloc=false);
58 
59  Event(EventType type, Time time, uint32_t size, const uint8_t* buf);
60 
67  Event(const Event& copy, bool alloc);
68 
69  ~Event();
70 
71  void assign(const Event& other);
72 
73  void set(const uint8_t* buf, uint32_t size, Time t);
74 
75  inline bool operator==(const Event& other) const {
76  if (_type != other._type || _time != other._time || _size != other._size) {
77  return false;
78  }
79  return !memcmp(_buf, other._buf, _size);
80  }
81 
82  inline bool operator!=(const Event& other) const { return ! operator==(other); }
83 
84  inline bool owns_buffer() const { return _owns_buf; }
85 
91  inline void set_buffer(uint32_t size, uint8_t* buf, bool own) {
92  if (_owns_buf) {
93  free(_buf);
94  _buf = NULL;
95  }
96  _size = size;
97  _buf = buf;
98  _owns_buf = own;
99  }
100 
101  inline void realloc(uint32_t size) {
102  if (_owns_buf) {
103  if (size > _size)
104  _buf = (uint8_t*) ::realloc(_buf, size);
105  } else {
106  _buf = (uint8_t*) ::malloc(size);
107  _owns_buf = true;
108  }
109 
110  _size = size;
111  }
112 
113  inline void clear() {
114  _type = NO_EVENT;
115  _time = Time();
116  _size = 0;
117  _buf = NULL;
118  }
119 
120 #endif // EVORAL_EVENT_ALLOC
121 
122  inline EventType event_type() const { return _type; }
123  inline Time time() const { return _time; }
124  inline uint32_t size() const { return _size; }
125  inline const uint8_t* buffer() const { return _buf; }
126  inline uint8_t* buffer() { return _buf; }
127 
128  inline bool is_midi () const { return _type == LIVE_MIDI_EVENT || _type == MIDI_EVENT; }
129  inline bool is_live_midi () const { return _type == LIVE_MIDI_EVENT; }
130 
131  inline void set_event_type(EventType t) { _type = t; }
132 
133  inline void set_time(Time t) { _time = t; }
134 
135  inline event_id_t id() const { return _id; }
136  inline void set_id(event_id_t n) { _id = n; }
137 
138  /* The following methods are type specific and only make sense for the
139  correct event type. It is the caller's responsibility to only call
140  methods which make sense for the given event type. Currently this means
141  they all only make sense for MIDI, but built-in support may be added for
142  other protocols in the future, or the internal representation may change
143  to be protocol agnostic. */
144 
145  uint8_t type() const { return _buf[0] & 0xF0; }
146  uint8_t channel() const { return _buf[0] & 0x0F; }
147  bool is_note_on() const { return type() == MIDI_CMD_NOTE_ON; }
148  bool is_note_off() const { return type() == MIDI_CMD_NOTE_OFF; }
149  bool is_note() const { return is_note_on() || is_note_off(); }
150  bool is_poly_pressure() const { return type() == MIDI_CMD_NOTE_PRESSURE; }
151  bool is_channel_pressure() const { return type() == MIDI_CMD_CHANNEL_PRESSURE; }
152  bool is_cc() const { return type() == MIDI_CMD_CONTROL; }
153  bool is_pgm_change() const { return type() == MIDI_CMD_PGM_CHANGE; }
154  bool is_pitch_bender() const { return type() == MIDI_CMD_BENDER; }
155  bool is_channel_event() const { return (0x80 <= type()) && (type() <= 0xE0); }
156  bool is_smf_meta_event() const { return _buf[0] == 0xFF; }
157  bool is_sysex() const { return _buf[0] == 0xF0 || _buf[0] == 0xF7; }
158  bool is_mtc_quarter() const { return _buf[0] == 0xF1 && size() == 1; }
159  bool is_spp() const { return _buf[0] == 0xF2 && size() == 1; }
160  bool is_song() const { return _buf[0] == 0xF3 && size() == 1; }
161  bool is_tune() const { return _buf[0] == 0xF6 && size() == 1; }
162  bool is_eox() const { return _buf[0] == 0xF7 && size() == 1; }
163  bool is_clock() const { return _buf[0] == 0xF8 && size() == 1; }
164  bool is_tick() const { return _buf[0] == 0xF9 && size() == 1; }
165  bool is_mtc_full() const { return (size() == 10 &&
166  _buf[0] == 0xF0 && _buf[1] == 0x7F &&
167  _buf[3] == 0x01 && _buf[4] == 0x01); }
168  bool is_realtime() const { return is_mtc_full() || ((_buf[0] >= 0xF1 && _buf[0] <= 0xfe) && size() == 1); }
169  uint8_t note() const { return _buf[1]; }
170  uint8_t velocity() const { return _buf[2]; }
171  uint8_t poly_note() const { return _buf[1]; }
172  uint8_t poly_pressure() const { return _buf[2]; }
173  uint8_t channel_pressure() const { return _buf[1]; }
174  uint8_t cc_number() const { return _buf[1]; }
175  uint8_t cc_value() const { return _buf[2]; }
176  uint8_t pgm_number() const { return _buf[1]; }
177  uint8_t pitch_bender_lsb() const { return _buf[1]; }
178  uint8_t pitch_bender_msb() const { return _buf[2]; }
179  uint16_t pitch_bender_value() const { return (uint16_t) ((0x7F & _buf[2]) << 7 | (0x7F & _buf[1])); }
180 
181  void set_channel(uint8_t channel) { _buf[0] = (0xF0 & _buf[0]) | (0x0F & channel); }
182  void set_type(uint8_t type) { _buf[0] = (0x0F & _buf[0]) | (0xF0 & type); }
183  void set_note(uint8_t num) { _buf[1] = num; }
184  void set_velocity(uint8_t val) { _buf[2] = val; }
185  void set_cc_number(uint8_t num) { _buf[1] = num; }
186  void set_cc_value(uint8_t val) { _buf[2] = val; }
187  void set_pgm_number(uint8_t num) { _buf[1] = num; }
188 
189  void scale_velocity (float factor) {
190  factor = std::max (factor, 0.0f);
191  set_velocity ((uint8_t) (std::min (127L, lrintf (velocity() * factor))));
192  }
193 
194  uint16_t value() const {
195  switch (type()) {
196  case MIDI_CMD_CONTROL:
197  return cc_value();
198  case MIDI_CMD_BENDER:
199  return pitch_bender_value();
201  return poly_pressure();
203  return channel_pressure();
204  case MIDI_CMD_PGM_CHANGE:
205  return pgm_number();
206  default:
207  return 0;
208  }
209  }
210 
211 protected:
213  Time _time;
214  uint32_t _size;
215  uint8_t* _buf;
217 #ifdef EVORAL_EVENT_ALLOC
218  bool _owns_buf;
219 #endif
220 };
221 
222 template<typename Time>
223 /*LIBEVORAL_API*/ std::ostream& operator<<(std::ostream& o, const Evoral::Event<Time>& ev) {
224  o << "Event #" << ev.id() << " type = " << ev.event_type() << " @ " << ev.time();
225  o << std::hex;
226  for (uint32_t n = 0; n < ev.size(); ++n) {
227  o << ' ' << (int) ev.buffer()[n];
228  }
229  o << std::dec;
230  return o;
231 }
232 
233 } // namespace Evoral
234 
235 #endif // EVORAL_EVENT_HPP
236 
bool is_eox() const
Definition: Event.h:162
uint16_t value() const
Definition: Event.h:194
void assign(const Event &other)
bool is_song() const
Definition: Event.h:160
void set(const uint8_t *buf, uint32_t size, Time t)
EventType event_type() const
Definition: Event.h:122
bool is_poly_pressure() const
Definition: Event.h:150
EventType _type
Type of event (application relative, NOT MIDI 'type')
Definition: Event.h:212
bool is_tick() const
Definition: Event.h:164
bool operator!=(const Event &other) const
Definition: Event.h:82
uint8_t note() const
Definition: Event.h:169
Event(const Event &copy, bool alloc)
bool is_channel_event() const
Definition: Event.h:155
void clear()
Definition: Event.h:113
uint8_t type() const
Definition: Event.h:145
void set_velocity(uint8_t val)
Definition: Event.h:184
bool is_midi() const
Definition: Event.h:128
bool is_sysex() const
Definition: Event.h:157
Time time() const
Definition: Event.h:123
uint32_t _size
Size of buffer in bytes.
Definition: Event.h:214
bool is_realtime() const
Definition: Event.h:168
uint8_t poly_pressure() const
Definition: Event.h:172
bool is_live_midi() const
Definition: Event.h:129
uint8_t cc_number() const
Definition: Event.h:174
Time _time
Time stamp of event.
Definition: Event.h:213
event_id_t id() const
Definition: Event.h:135
bool is_tune() const
Definition: Event.h:161
uint8_t * _buf
Event contents (e.g. raw MIDI data)
Definition: Event.h:215
bool is_mtc_full() const
Definition: Event.h:165
uint8_t pitch_bender_lsb() const
Definition: Event.h:177
const uint8_t * buffer() const
Definition: Event.h:125
void scale_velocity(float factor)
Definition: Event.h:189
bool is_spp() const
Definition: Event.h:159
void set_event_type(EventType t)
Definition: Event.h:131
uint8_t channel() const
Definition: Event.h:146
bool owns_buffer() const
Definition: Event.h:84
uint8_t * buffer()
Definition: Event.h:126
bool is_mtc_quarter() const
Definition: Event.h:158
void realloc(uint32_t size)
Definition: Event.h:101
uint8_t channel_pressure() const
Definition: Event.h:173
bool is_channel_pressure() const
Definition: Event.h:151
bool is_smf_meta_event() const
Definition: Event.h:156
void set_id(event_id_t n)
Definition: Event.h:136
uint8_t cc_value() const
Definition: Event.h:175
bool is_note_off() const
Definition: Event.h:148
event_id_t _id
Unique event ID.
Definition: Event.h:216
Event(EventType type=NO_EVENT, Time time=Time(), uint32_t size=0, uint8_t *buf=NULL, bool alloc=false)
uint32_t size() const
Definition: Event.h:124
bool is_pgm_change() const
Definition: Event.h:153
uint8_t pgm_number() const
Definition: Event.h:176
void set_pgm_number(uint8_t num)
Definition: Event.h:187
bool is_cc() const
Definition: Event.h:152
Event(EventType type, Time time, uint32_t size, const uint8_t *buf)
void set_channel(uint8_t channel)
Definition: Event.h:181
void set_time(Time t)
Definition: Event.h:133
bool is_pitch_bender() const
Definition: Event.h:154
void set_cc_value(uint8_t val)
Definition: Event.h:186
bool is_clock() const
Definition: Event.h:163
void set_note(uint8_t num)
Definition: Event.h:183
uint8_t pitch_bender_msb() const
Definition: Event.h:178
void set_type(uint8_t type)
Definition: Event.h:182
uint8_t poly_note() const
Definition: Event.h:171
bool is_note_on() const
Definition: Event.h:147
uint16_t pitch_bender_value() const
Definition: Event.h:179
uint8_t velocity() const
Definition: Event.h:170
bool operator==(const Event &other) const
Definition: Event.h:75
void set_cc_number(uint8_t num)
Definition: Event.h:185
void set_buffer(uint32_t size, uint8_t *buf, bool own)
Definition: Event.h:91
bool _owns_buf
Whether buffer is locally allocated.
Definition: Event.h:218
bool is_note() const
Definition: Event.h:149
#define LIBEVORAL_API
#define MIDI_CMD_NOTE_PRESSURE
Definition: midi_events.h:108
#define MIDI_CMD_NOTE_ON
Definition: midi_events.h:107
#define MIDI_CMD_BENDER
Definition: midi_events.h:112
#define MIDI_CMD_PGM_CHANGE
Definition: midi_events.h:110
#define MIDI_CMD_CONTROL
Definition: midi_events.h:109
#define MIDI_CMD_CHANNEL_PRESSURE
Definition: midi_events.h:111
#define MIDI_CMD_NOTE_OFF
Definition: midi_events.h:106
Definition: editor.h:86
int32_t event_id_t
event_id_t next_event_id()
event_id_t event_id_counter()
std::ostream & operator<<(std::ostream &o, const Evoral::Event< Time > &ev)
Definition: Event.h:223
void init_event_id_counter(event_id_t n)
bool operator==(const ProcessorSelection &a, const ProcessorSelection &b)