From 08fffeffec10beb708610fd35eb9e7c35365d446 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 6 Nov 2016 22:04:35 -0500 Subject: Remove Evoral::MIDIEvent It is slightly questionable whether type specific methods like velocity() belong on Event at all, these may be better off as free functions. However the code currently uses them as methods in many places, and it seems like a step in the right direction, since, for example, we might some day have events that have a velocity but aren't stored as MIDI messages (e.g. if Ardour uses an internal musical model that is more expressive). In any case, the former inheritance and plethora of sloppy casts is definitely not the right thing. --- libs/evoral/evoral/Event.hpp | 119 +++++++++++++++++++++++++------------ libs/evoral/evoral/MIDIEvent.hpp | 115 ----------------------------------- libs/evoral/evoral/MIDIXML.hpp | 6 +- libs/evoral/evoral/Note.hpp | 6 +- libs/evoral/evoral/PatchChange.hpp | 10 ++-- libs/evoral/evoral/Sequence.hpp | 6 +- 6 files changed, 96 insertions(+), 166 deletions(-) delete mode 100644 libs/evoral/evoral/MIDIEvent.hpp (limited to 'libs/evoral/evoral') diff --git a/libs/evoral/evoral/Event.hpp b/libs/evoral/evoral/Event.hpp index cbb62e2f4c..526513b3fe 100644 --- a/libs/evoral/evoral/Event.hpp +++ b/libs/evoral/evoral/Event.hpp @@ -1,5 +1,5 @@ /* This file is part of Evoral. - * Copyright (C) 2008 David Robillard + * Copyright (C) 2008-2016 David Robillard * Copyright (C) 2000-2008 Paul Davis * * Evoral is free software; you can redistribute it and/or modify it under the @@ -24,8 +24,9 @@ #include #include -#include "evoral/visibility.h" +#include "evoral/midi_events.h" #include "evoral/types.hpp" +#include "evoral/visibility.h" /** If this is not defined, all methods of MidiEvent are RT safe * but MidiEvent will never deep copy and (depending on the scenario) @@ -37,7 +38,7 @@ namespace Evoral { LIBEVORAL_API event_id_t event_id_counter(); LIBEVORAL_API event_id_t next_event_id(); -LIBEVORAL_API void init_event_id_counter(event_id_t n); +LIBEVORAL_API void init_event_id_counter(event_id_t n); /** An event (much like a type generic jack_midi_event_t) * @@ -47,9 +48,9 @@ template class LIBEVORAL_API Event { public: #ifdef EVORAL_EVENT_ALLOC - Event (EventType type=0, Time time=Time(), uint32_t size=0, uint8_t* buf=NULL, bool alloc=false); + Event(EventType type=0, Time time=Time(), uint32_t size=0, uint8_t* buf=NULL, bool alloc=false); - Event (EventType type, Time time, uint32_t size, const uint8_t* buf); + Event(EventType type, Time time, uint32_t size, const uint8_t* buf); /** Copy \a copy. * @@ -59,33 +60,20 @@ public: */ Event(const Event& copy, bool alloc); - ~Event(); + ~Event(); - void assign (const Event& other); + void assign(const Event& other); void set(const uint8_t* buf, uint32_t size, Time t); inline bool operator==(const Event& other) const { - if (_type != other._type) + if (_type != other._type || + _nominal_time != other._nominal_time || + _original_time != other._original_time || + _size != other._size) { return false; - - if (_nominal_time != other._nominal_time) - return false; - - if (_original_time != other._original_time) - return false; - - if (_size != other._size) - return false; - - if (_buf == other._buf) - return true; - - for (uint32_t i=0; i < _size; ++i) - if (_buf[i] != other._buf[i]) - return false; - - return true; + } + return !memcmp(_buf, other._buf, _size); } inline bool operator!=(const Event& other) const { return ! operator==(other); } @@ -127,10 +115,6 @@ public: _buf = NULL; } -#else - - inline void set_buffer(uint8_t* buf) { _buf = buf; } - #endif // EVORAL_EVENT_ALLOC inline EventType event_type() const { return _type; } @@ -148,15 +132,76 @@ public: inline event_id_t id() const { return _id; } inline void set_id(event_id_t n) { _id = n; } + /* The following methods are type specific and only make sense for the + correct event type. It is the caller's responsibility to only call + methods which make sense for the given event type. Currently this means + they all only make sense for MIDI, but built-in support may be added for + other protocols in the future, or the internal representation may change + to be protocol agnostic. */ + + uint8_t type() const { return _buf[0] & 0xF0; } + uint8_t channel() const { return _buf[0] & 0x0F; } + bool is_note_on() const { return type() == MIDI_CMD_NOTE_ON; } + bool is_note_off() const { return type() == MIDI_CMD_NOTE_OFF; } + bool is_note() const { return is_note_on() || is_note_off(); } + bool is_poly_pressure() const { return type() == MIDI_CMD_NOTE_PRESSURE; } + bool is_channel_pressure() const { return type() == MIDI_CMD_CHANNEL_PRESSURE; } + bool is_cc() const { return type() == MIDI_CMD_CONTROL; } + bool is_pgm_change() const { return type() == MIDI_CMD_PGM_CHANGE; } + bool is_pitch_bender() const { return type() == MIDI_CMD_BENDER; } + bool is_channel_event() const { return (0x80 <= type()) && (type() <= 0xE0); } + bool is_smf_meta_event() const { return _buf[0] == 0xFF; } + bool is_sysex() const { return _buf[0] == 0xF0 || _buf[0] == 0xF7; } + bool is_spp() const { return _buf[0] == 0xF2 && size() == 1; } + bool is_mtc_quarter() const { return _buf[0] == 0xF1 && size() == 1; } + bool is_mtc_full() const { return (size() == 10 && + _buf[0] == 0xF0 && _buf[1] == 0x7F && + _buf[3] == 0x01 && _buf[4] == 0x01); } + + uint8_t note() const { return _buf[1]; } + uint8_t velocity() const { return _buf[2]; } + uint8_t poly_note() const { return _buf[1]; } + uint8_t poly_pressure() const { return _buf[2]; } + uint8_t channel_pressure() const { return _buf[1]; } + uint8_t cc_number() const { return _buf[1]; } + uint8_t cc_value() const { return _buf[2]; } + uint8_t pgm_number() const { return _buf[1]; } + uint8_t pitch_bender_lsb() const { return _buf[1]; } + uint8_t pitch_bender_msb() const { return _buf[2]; } + uint16_t pitch_bender_value() const { return ((0x7F & _buf[2]) << 7 | (0x7F & _buf[1])); } + + void set_channel(uint8_t channel) { _buf[0] = (0xF0 & _buf[0]) | (0x0F & channel); } + void set_type(uint8_t type) { _buf[0] = (0x0F & _buf[0]) | (0xF0 & type); } + void set_note(uint8_t num) { _buf[1] = num; } + void set_velocity(uint8_t val) { _buf[2] = val; } + void set_cc_number(uint8_t num) { _buf[1] = num; } + void set_cc_value(uint8_t val) { _buf[2] = val; } + void set_pgm_number(uint8_t num) { _buf[1] = num; } + + uint16_t value() const { + switch (type()) { + case MIDI_CMD_CONTROL: + return cc_value(); + case MIDI_CMD_BENDER: + return pitch_bender_value(); + case MIDI_CMD_NOTE_PRESSURE: + return poly_pressure(); + case MIDI_CMD_CHANNEL_PRESSURE: + return channel_pressure(); + default: + return 0; + } + } + protected: - EventType _type; /**< Type of event (application relative, NOT MIDI 'type') */ - Time _original_time; /**< Sample index (or beat time) at which event is valid */ - Time _nominal_time; /**< Quantized version of _time, used in preference */ - uint32_t _size; /**< Number of uint8_ts of data in \a buffer */ - uint8_t* _buf; /**< Raw MIDI data */ - event_id_t _id; /** UUID for each event, should probably be 64bit or at least unsigned */ + EventType _type; ///< Type of event (application relative, NOT MIDI 'type') + Time _original_time; ///< Time stamp of event + Time _nominal_time; ///< Quantized version of _time, used in preference + uint32_t _size; ///< Size of buffer in bytes + uint8_t* _buf; ///< Event contents (e.g. raw MIDI data) + event_id_t _id; ///< Unique event ID #ifdef EVORAL_EVENT_ALLOC - bool _owns_buf; /**< Whether buffer is locally allocated */ + bool _owns_buf; ///< Whether buffer is locally allocated #endif }; diff --git a/libs/evoral/evoral/MIDIEvent.hpp b/libs/evoral/evoral/MIDIEvent.hpp deleted file mode 100644 index e8320c3e35..0000000000 --- a/libs/evoral/evoral/MIDIEvent.hpp +++ /dev/null @@ -1,115 +0,0 @@ -/* This file is part of Evoral. - * 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 - */ - -#ifndef EVORAL_MIDI_EVENT_HPP -#define EVORAL_MIDI_EVENT_HPP - -#include -#include - -#include "evoral/visibility.h" -#include "evoral/Event.hpp" -#include "evoral/midi_events.h" - -namespace Evoral { - -/** MIDI helper functions for an Event. - * - * This class contains no data, an Evoral::Event can be cast to a MIDIEvent - * but the application must make sure the Event actually contains - * valid MIDI data for these functions to make sense. - */ -template -class /*LIBEVORAL_API*/ MIDIEvent : public Event