remove old midi-note name API
[ardour.git] / libs / evoral / evoral / Event.hpp
index 1dd081a5b90575336e0b10e45f2abdd667405044..cbb62e2f4cc289fade9ad1c0d31e51d1a5e050bd 100644 (file)
@@ -1,16 +1,16 @@
 /* This file is part of Evoral.
- * Copyright (C) 2008 Dave Robillard <http://drobilla.net>
+ * Copyright (C) 2008 David Robillard <http://drobilla.net>
  * 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_EVENT_HPP
 #define EVORAL_EVENT_HPP
 
-#include <stdint.h>
 #include <cstdlib>
 #include <cstring>
 #include <sstream>
-#include <assert.h>
-#include <evoral/types.hpp>
+#include <stdint.h>
 
+#include "evoral/visibility.h"
+#include "evoral/types.hpp"
 
 /** If this is not defined, all methods of MidiEvent are RT safe
  * but MidiEvent will never deep copy and (depending on the scenario)
- * may not be usable in STL containers, signals, etc. 
+ * may not be usable in STL containers, signals, etc.
  */
 #define EVORAL_EVENT_ALLOC 1
 
 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);
 
 /** An event (much like a type generic jack_midi_event_t)
  *
- * time is either a frame time (from/to Jack) or a beat time (internal
- * tempo time, used in MidiModel) depending on context.
+ * Template parameter Time is the type of the time stamp used for this event.
  */
-struct Event {
+template<typename Time>
+class LIBEVORAL_API Event {
+public:
 #ifdef EVORAL_EVENT_ALLOC
-       Event(EventType type=0, EventTime t=0, uint32_t s=0, uint8_t* b=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);
+
        /** Copy \a copy.
-        * 
+        *
         * If \a alloc is true, the buffer will be copied and this method
         * is NOT REALTIME SAFE.  Otherwise both events share a buffer and
         * memory management semantics are the caller's problem.
         */
        Event(const Event& copy, bool alloc);
-       
-       ~Event();
-
-       inline const Event& operator=(const Event& copy) {
-               _type = copy._type;
-               _time = copy._time;
-               if (_owns_buffer) {
-                       if (copy._buffer) {
-                               if (copy._size > _size) {
-                                       _buffer = (uint8_t*)::realloc(_buffer, copy._size);
-                               }
-                               memcpy(_buffer, copy._buffer, copy._size);
-                       } else {
-                               free(_buffer);
-                               _buffer = NULL;
-                       }
-               } else {
-                       _buffer = copy._buffer;
-               }
 
-               _size = copy._size;
-               return *this;
-       }
+        ~Event();
 
-       inline void shallow_copy(const Event& copy) {
-               if (_owns_buffer) {
-                       free(_buffer);
-                       _buffer = false;
-                       _owns_buffer = false;
-               }
-
-               _type = copy._type;
-               _time = copy._time;
-               _size = copy._size;
-               _buffer = copy._buffer;
-       }
-       
-       inline void set(uint8_t* buf, uint32_t size, EventTime t) {
-               if (_owns_buffer) {
-                       if (_size < size) {
-                               _buffer = (uint8_t*) ::realloc(_buffer, size);
-                       }
-                       memcpy (_buffer, buf, size);
-               } else {
-                       _buffer = buf;
-               }
+       void assign (const Event& other);
 
-               _time = t;
-               _size = size;
-       }
+       void set(const uint8_t* buf, uint32_t size, Time t);
 
        inline bool operator==(const Event& other) const {
                if (_type != other._type)
                        return false;
 
-               if (_time != other._time)
+               if (_nominal_time != other._nominal_time)
+                       return false;
+
+               if (_original_time != other._original_time)
                        return false;
 
                if (_size != other._size)
                        return false;
 
-               if (_buffer == other._buffer)
+               if (_buf == other._buf)
                        return true;
 
                for (uint32_t i=0; i < _size; ++i)
-                       if (_buffer[i] != other._buffer[i])
+                       if (_buf[i] != other._buf[i])
                                return false;
 
                return true;
        }
-       
+
        inline bool operator!=(const Event& other) const { return ! operator==(other); }
 
-       inline bool owns_buffer() const { return _owns_buffer; }
-       
+       inline bool owns_buffer() const { return _owns_buf; }
+
+       /** set event data (e.g. midi data)
+        * @param size number of bytes
+        * @param buf raw 8bit data
+        * @param own set to true if the buffer owns the data (copy, allocate/free) or false to reference previously allocated data.
+        */
        inline void set_buffer(uint32_t size, uint8_t* buf, bool own) {
-               if (_owns_buffer) {
-                       free(_buffer);
-                       _buffer = NULL;
+               if (_owns_buf) {
+                       free(_buf);
+                       _buf = NULL;
                }
-               _size = size;
-               _buffer = buf;
-               _owns_buffer = own;
+               _size     = size;
+               _buf      = buf;
+               _owns_buf = own;
        }
 
        inline void realloc(uint32_t size) {
-               if (_owns_buffer) {
+               if (_owns_buf) {
                        if (size > _size)
-                               _buffer = (uint8_t*) ::realloc(_buffer, size);
+                               _buf = (uint8_t*) ::realloc(_buf, size);
                } else {
-                       _buffer = (uint8_t*) ::malloc(size);
-                       _owns_buffer = true;
+                       _buf = (uint8_t*) ::malloc(size);
+                       _owns_buf = true;
                }
 
                _size = size;
        }
-       
+
        inline void clear() {
-               _type = 0;
-               _time = 0;
-               _size = 0;
-               _buffer = NULL;
+               _type          = 0;
+               _original_time = Time();
+               _nominal_time  = Time();
+               _size          = 0;
+               _buf           = NULL;
        }
 
 #else
 
-       inline void set_buffer(uint8_t* buf) { _buffer = buf; }
+       inline void set_buffer(uint8_t* buf) { _buf = buf; }
 
 #endif // EVORAL_EVENT_ALLOC
 
-       inline EventType   event_type()            const { return _type; }
-       inline void        set_event_type(EventType t)   { _type = t; }
-       inline EventTime   time()                  const { return _time; }
-       inline EventTime&  time()                        { return _time; }
-       inline uint32_t    size()                  const { return _size; }
-       inline uint32_t&   size()                        { return _size; }
+       inline EventType      event_type()    const { return _type; }
+       inline Time           time()          const { return _nominal_time; }
+       inline Time           original_time() const { return _original_time; }
+       inline uint32_t       size()          const { return _size; }
+       inline const uint8_t* buffer()        const { return _buf; }
+       inline uint8_t*       buffer()              { return _buf; }
 
-       inline const uint8_t* buffer()             const { return _buffer; }
-       inline uint8_t*&      buffer()                   { return _buffer; }
+       inline void set_event_type(EventType t) { _type = t; }
 
-protected:
-       EventType _type;   /**< Type of event (application relative, NOT MIDI 'type') */
-       EventTime _time;   /**< Sample index (or beat time) at which event is valid */
-       uint32_t  _size;   /**< Number of uint8_ts of data in \a buffer */
-       uint8_t*  _buffer; /**< Raw MIDI data */
+       void set_time(Time);
+       void set_original_time(Time);
 
+       inline event_id_t id() const           { return _id; }
+       inline void       set_id(event_id_t n) { _id = n; }
+
+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 */
 #ifdef EVORAL_EVENT_ALLOC
-       bool _owns_buffer; /**< Whether buffer is locally allocated */
+       bool       _owns_buf; /**< Whether buffer is locally allocated */
 #endif
 };
 
+template<typename Time>
+/*LIBEVORAL_API*/ std::ostream& operator<<(std::ostream& o, const Evoral::Event<Time>& ev) {
+       o << "Event #" << ev.id() << " type = " << ev.event_type() << " @ " << ev.time();
+       o << std::hex;
+       for (uint32_t n = 0; n < ev.size(); ++n) {
+               o << ' ' << (int) ev.buffer()[n];
+       }
+       o << std::dec;
+       return o;
+}
 
 } // namespace Evoral