3e8e05fa3bf793cc94bc2645db5d566047348590
[ardour.git] / libs / evoral / evoral / Event.hpp
1 /* This file is part of Evoral.
2  * Copyright (C) 2008 Dave Robillard <http://drobilla.net>
3  * Copyright (C) 2000-2008 Paul Davis
4  * 
5  * Evoral is free software; you can redistribute it and/or modify it under the
6  * terms of the GNU General Public License as published by the Free Software
7  * Foundation; either version 2 of the License, or (at your option) any later
8  * version.
9  * 
10  * Evoral is distributed in the hope that it will be useful, but WITHOUT ANY
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
13  * 
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #ifndef EVORAL_EVENT_HPP
20 #define EVORAL_EVENT_HPP
21
22 #include <stdint.h>
23 #include <cstdlib>
24 #include <cstring>
25 #include <sstream>
26 #include <assert.h>
27 #include "evoral/types.hpp"
28
29
30 /** If this is not defined, all methods of MidiEvent are RT safe
31  * but MidiEvent will never deep copy and (depending on the scenario)
32  * may not be usable in STL containers, signals, etc. 
33  */
34 #define EVORAL_EVENT_ALLOC 1
35
36 namespace Evoral {
37
38
39 /** An event (much like a type generic jack_midi_event_t)
40  *
41  * Template parameter Time is the type of the time stamp used for this event.
42  */
43 template<typename Time>
44 struct Event {
45 #ifdef EVORAL_EVENT_ALLOC
46         Event(EventType type=0, Time time=0, uint32_t size=0, uint8_t* buf=NULL, bool alloc=false);
47         
48         /** Copy \a copy.
49          * 
50          * If \a alloc is true, the buffer will be copied and this method
51          * is NOT REALTIME SAFE.  Otherwise both events share a buffer and
52          * memory management semantics are the caller's problem.
53          */
54         Event(const Event& copy, bool alloc);
55         
56         ~Event();
57
58         inline const Event& operator=(const Event& copy) {
59                 _type = copy._type;
60                 _original_time = copy._original_time;
61                 _nominal_time = copy._nominal_time;
62                 if (_owns_buf) {
63                         if (copy._buf) {
64                                 if (copy._size > _size) {
65                                         _buf = (uint8_t*)::realloc(_buf, copy._size);
66                                 }
67                                 memcpy(_buf, copy._buf, copy._size);
68                         } else {
69                                 free(_buf);
70                                 _buf = NULL;
71                         }
72                 } else {
73                         _buf = copy._buf;
74                 }
75
76                 _size = copy._size;
77                 return *this;
78         }
79
80         inline void shallow_copy(const Event& copy) {
81                 if (_owns_buf) {
82                         free(_buf);
83                         _buf = false;
84                         _owns_buf = false;
85                 }
86
87                 _type = copy._type;
88                 _original_time = copy._nominal_time;
89                 _nominal_time = copy._nominal_time;
90                 _size = copy._size;
91                 _buf  = copy._buf;
92         }
93         
94         inline void set(uint8_t* buf, uint32_t size, Time t) {
95                 if (_owns_buf) {
96                         if (_size < size) {
97                                 _buf = (uint8_t*) ::realloc(_buf, size);
98                         }
99                         memcpy (_buf, buf, size);
100                 } else {
101                         _buf = buf;
102                 }
103
104                 _original_time = t;
105                 _nominal_time = t;
106                 _size = size;
107         }
108
109         inline bool operator==(const Event& other) const {
110                 if (_type != other._type)
111                         return false;
112
113                 if (_nominal_time != other._nominal_time)
114                         return false;
115
116                 if (_original_time != other._original_time)
117                         return false;
118
119                 if (_size != other._size)
120                         return false;
121
122                 if (_buf == other._buf)
123                         return true;
124
125                 for (uint32_t i=0; i < _size; ++i)
126                         if (_buf[i] != other._buf[i])
127                                 return false;
128
129                 return true;
130         }
131         
132         inline bool operator!=(const Event& other) const { return ! operator==(other); }
133
134         inline bool owns_buffer() const { return _owns_buf; }
135         
136         inline void set_buffer(uint32_t size, uint8_t* buf, bool own) {
137                 if (_owns_buf) {
138                         free(_buf);
139                         _buf = NULL;
140                 }
141                 _size     = size;
142                 _buf      = buf;
143                 _owns_buf = own;
144         }
145
146         inline void realloc(uint32_t size) {
147                 if (_owns_buf) {
148                         if (size > _size)
149                                 _buf = (uint8_t*) ::realloc(_buf, size);
150                 } else {
151                         _buf = (uint8_t*) ::malloc(size);
152                         _owns_buf = true;
153                 }
154
155                 _size = size;
156         }
157         
158         inline void clear() {
159                 _type = 0;
160                 _original_time = 0;
161                 _nominal_time = 0;
162                 _size = 0;
163                 _buf  = NULL;
164         }
165
166 #else
167
168         inline void set_buffer(uint8_t* buf) { _buf = buf; }
169
170 #endif // EVORAL_EVENT_ALLOC
171
172         inline EventType   event_type()            const { return _type; }
173         inline void        set_event_type(EventType t)   { _type = t; }
174         inline Time        time()                  const { return _nominal_time; }
175         inline Time&       time()                        { return _nominal_time; }
176         inline Time        original_time()         const { return _original_time; }
177         inline Time&       original_time()               { return _original_time; }
178         inline uint32_t    size()                  const { return _size; }
179         inline uint32_t&   size()                        { return _size; }
180
181         inline const uint8_t* buffer()             const { return _buf; }
182         inline uint8_t*&      buffer()                   { return _buf; }
183
184 protected:
185         EventType _type; /**< Type of event (application relative, NOT MIDI 'type') */
186         Time      _original_time; /**< Sample index (or beat time) at which event is valid */
187         Time      _nominal_time; /**< quantized version of _time, used in preference */
188         uint32_t  _size; /**< Number of uint8_ts of data in \a buffer */
189         uint8_t*  _buf;  /**< Raw MIDI data */
190
191 #ifdef EVORAL_EVENT_ALLOC
192         bool _owns_buf; /**< Whether buffer is locally allocated */
193 #endif
194 };
195
196
197 } // namespace Evoral
198
199
200 template<typename Time>
201 std::ostream& operator<<(std::ostream& o, const Evoral::Event<Time>& ev) {
202         o << "Event type = " << ev.event_type() << " @ " << " @ " << ev.time() << "\n\t";
203         o << std::hex;
204         for (uint32_t n = 0; n < ev.size(); ++n) {
205                 o << (int) ev.buffer()[n] << ' ';
206         }
207         o << std::dec << std::endl;
208         return o;
209 }
210
211
212 #endif // EVORAL_EVENT_HPP
213