unused but slightly tricky code to add track name/instrument to an SMF file when...
[ardour.git] / libs / evoral / src / Event.cpp
1 /* This file is part of Evoral.
2  * Copyright (C) 2008 David 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 #include <glib.h>
20
21 #include "evoral/Event.hpp"
22 #include "evoral/Beats.hpp"
23
24 namespace Evoral {
25
26 static event_id_t _event_id_counter = 0;
27
28 event_id_t
29 event_id_counter()
30 {
31         return g_atomic_int_get (&_event_id_counter);
32 }
33
34 void
35 init_event_id_counter(event_id_t n)
36 {
37         g_atomic_int_set (&_event_id_counter, n);
38 }
39
40 event_id_t
41 next_event_id ()
42 {
43         /* TODO: handle 31bit overflow , event_id_t is an int32_t,
44          * and libsmf only supports loading uint32_t vlq's, see smf_extract_vlq()
45          *
46          * event-IDs only have to be unique per .mid file.
47          * Previously (Ardour 4.2ish) Ardour re-generated those IDs when loading the
48          * file but that lead to .mid files being modified on every load/save.
49          *
50          * current user-record: is event-counter="276390506" (just abov 2^28)
51          */
52         return g_atomic_int_add (&_event_id_counter, 1);
53 }
54
55 #ifdef EVORAL_EVENT_ALLOC
56
57 template<typename Timestamp>
58 Event<Timestamp>::Event(EventType type, Timestamp time, uint32_t size, uint8_t* buf, bool alloc)
59         : _type(type)
60         , _time(time)
61         , _size(size)
62         , _buf(buf)
63         , _id(-1)
64         , _owns_buf(alloc)
65 {
66         if (alloc) {
67                 _buf = (uint8_t*)malloc(_size);
68                 if (buf) {
69                         memcpy(_buf, buf, _size);
70                 } else {
71                         memset(_buf, 0, _size);
72                 }
73         }
74 }
75
76 template<typename Timestamp>
77 Event<Timestamp>::Event(EventType      type,
78                         Timestamp      time,
79                         uint32_t       size,
80                         const uint8_t* buf)
81         : _type(type)
82         , _time(time)
83         , _size(size)
84         , _buf((uint8_t*)malloc(size))
85         , _id(-1)
86         , _owns_buf(true)
87 {
88         memcpy(_buf, buf, _size);
89 }
90
91 template<typename Timestamp>
92 Event<Timestamp>::Event(const Event& copy, bool owns_buf)
93         : _type(copy._type)
94         , _time(copy._time)
95         , _size(copy._size)
96         , _buf(copy._buf)
97         , _id (next_event_id ())
98         , _owns_buf(owns_buf)
99 {
100         if (owns_buf) {
101                 _buf = (uint8_t*)malloc(_size);
102                 if (copy._buf) {
103                         memcpy(_buf, copy._buf, _size);
104                 } else {
105                         memset(_buf, 0, _size);
106                 }
107         }
108 }
109
110 template<typename Timestamp>
111 Event<Timestamp>::~Event() {
112         if (_owns_buf) {
113                 free(_buf);
114         }
115 }
116
117 template<typename Timestamp>
118 void
119 Event<Timestamp>::assign(const Event& other)
120 {
121         _id = other._id;
122         _type = other._type;
123         _time = other._time;
124         _owns_buf = other._owns_buf;
125         if (_owns_buf) {
126                 if (other._buf) {
127                         if (other._size > _size) {
128                                 _buf = (uint8_t*)::realloc(_buf, other._size);
129                         }
130                         memcpy(_buf, other._buf, other._size);
131                 } else {
132                         free(_buf);
133                         _buf = NULL;
134                 }
135         } else {
136                 _buf = other._buf;
137         }
138
139         _size = other._size;
140 }
141
142 template<typename Timestamp>
143 void
144 Event<Timestamp>::set (const uint8_t* buf, uint32_t size, Timestamp t)
145 {
146         if (_owns_buf) {
147                 if (_size < size) {
148                         _buf = (uint8_t*) ::realloc(_buf, size);
149                 }
150                 memcpy (_buf, buf, size);
151         } else {
152                 /* XXX this is really dangerous given the
153                    const-ness of buf. The API should really
154                    intervene here.
155                 */
156                 _buf = const_cast<uint8_t*> (buf);
157         }
158
159         _time = t;
160         _size = size;
161 }
162
163 #endif // EVORAL_EVENT_ALLOC
164
165 template class Event<Evoral::Beats>;
166 template class Event<double>;
167 template class Event<int64_t>;
168
169 } // namespace Evoral
170