fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / midi_buffer.cc
1 /*
2     Copyright (C) 2006-2007 Paul Davis
3     Author: David Robillard
4
5     This program is free software; you can redistribute it and/or modify it
6     under the terms of the GNU General Public License as published by the Free
7     Software Foundation; either version 2 of the License, or (at your option)
8     any later version.
9
10     This program is distributed in the hope that it will be useful, but WITHOUT
11     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13     for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <iostream>
21
22 #include "pbd/malign.h"
23 #include "pbd/compose.h"
24 #include "pbd/debug.h"
25 #include "pbd/stacktrace.h"
26
27 #include "ardour/debug.h"
28 #include "ardour/midi_buffer.h"
29 #include "ardour/port.h"
30
31 using namespace std;
32 using namespace ARDOUR;
33 using namespace PBD;
34
35 // FIXME: mirroring for MIDI buffers?
36 MidiBuffer::MidiBuffer(size_t capacity)
37         : Buffer (DataType::MIDI)
38         , _data (0)
39         , _size (0)
40 {
41         if (capacity) {
42                 resize (capacity);
43                 silence (capacity);
44         }
45 }
46
47 MidiBuffer::~MidiBuffer()
48 {
49         cache_aligned_free(_data);
50 }
51
52 void
53 MidiBuffer::resize(size_t size)
54 {
55         if (_data && size < _capacity) {
56
57                 if (_size < size) {
58                         /* truncate */
59                         _size = size;
60                 }
61
62                 return;
63         }
64
65         cache_aligned_free (_data);
66
67         cache_aligned_malloc ((void**) &_data, size);
68
69         _size = 0;
70         _capacity = size;
71
72         assert(_data);
73 }
74
75 void
76 MidiBuffer::copy(const MidiBuffer& copy)
77 {
78         assert(_capacity >= copy._size);
79         _size = copy._size;
80         memcpy(_data, copy._data, copy._size);
81 }
82
83 void
84 MidiBuffer::copy(MidiBuffer const * const copy)
85 {
86         assert(_capacity >= copy->size ());
87         _size = copy->size ();
88         memcpy(_data, copy->data(), _size);
89 }
90
91
92 /** Read events from @a src starting at time @a offset into the START of this buffer, for
93  * time duration @a nframes.  Relative time, where 0 = start of buffer.
94  *
95  * Note that offset and nframes refer to sample time, NOT buffer offsets or event counts.
96  */
97 void
98 MidiBuffer::read_from (const Buffer& src, framecnt_t nframes, framecnt_t dst_offset, framecnt_t /* src_offset*/)
99 {
100         assert (src.type() == DataType::MIDI);
101         assert (&src != this);
102
103         const MidiBuffer& msrc = (const MidiBuffer&) src;
104
105         assert (_capacity >= msrc.size());
106
107         if (dst_offset == 0) {
108                 clear ();
109                 assert (_size == 0);
110         }
111
112         framecnt_t offset = Port::port_offset();
113
114         for (MidiBuffer::const_iterator i = msrc.begin(); i != msrc.end(); ++i) {
115                 const Evoral::MIDIEvent<TimeType> ev(*i, false);
116                 if (ev.time() >= offset && ev.time() < (nframes + offset)) {
117                         push_back (ev);
118                 } else {
119                         cerr << "MIDI event @ " <<  ev.time() << " skipped, not within range "
120                              << offset << " .. " << (nframes + offset) << ":";
121                                 for (size_t xx = 0; xx < ev.size(); ++xx) {
122                                         cerr << ' ' << hex << (int) ev.buffer()[xx];
123                                 }
124                                 cerr << dec << endl;
125                 }
126         }
127
128         _silent = src.silent();
129 }
130
131 void
132 MidiBuffer::merge_from (const Buffer& src, framecnt_t /*nframes*/, framecnt_t /*dst_offset*/, framecnt_t /*src_offset*/)
133 {
134         const MidiBuffer* mbuf = dynamic_cast<const MidiBuffer*>(&src);
135         assert (mbuf);
136         assert (mbuf != this);
137
138         /* XXX use nframes, and possible offsets */
139         merge_in_place (*mbuf);
140 }
141
142 /** Push an event into the buffer.
143  *
144  * Note that the raw MIDI pointed to by ev will be COPIED and unmodified.
145  * That is, the caller still owns it, if it needs freeing it's Not My Problem(TM).
146  * Realtime safe.
147  * @return false if operation failed (not enough room)
148  */
149 bool
150 MidiBuffer::push_back(const Evoral::MIDIEvent<TimeType>& ev)
151 {
152         return push_back (ev.time(), ev.size(), ev.buffer());
153 }
154
155
156 /** Push MIDI data into the buffer.
157  *
158  * Note that the raw MIDI pointed to by @param data will be COPIED and unmodified.
159  * That is, the caller still owns it, if it needs freeing it's Not My Problem(TM).
160  * Realtime safe.
161  * @return false if operation failed (not enough room)
162  */
163 bool
164 MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
165 {
166         const size_t stamp_size = sizeof(TimeType);
167
168 #ifndef NDEBUG
169         if (DEBUG_ENABLED(DEBUG::MidiIO)) {
170                 DEBUG_STR_DECL(a);
171                 DEBUG_STR_APPEND(a, string_compose ("midibuffer %1 push event @ %2 sz %3 ", this, time, size));
172                 for (size_t i=0; i < size; ++i) {
173                         DEBUG_STR_APPEND(a,hex);
174                         DEBUG_STR_APPEND(a,"0x");
175                         DEBUG_STR_APPEND(a,(int)data[i]);
176                         DEBUG_STR_APPEND(a,' ');
177                 }
178                 DEBUG_STR_APPEND(a,'\n');
179                 DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
180         }
181 #endif
182
183         if (_size + stamp_size + size >= _capacity) {
184                 return false;
185         }
186
187         if (!Evoral::midi_event_is_valid(data, size)) {
188                 return false;
189         }
190
191         uint8_t* const write_loc = _data + _size;
192         *(reinterpret_cast<TimeType*>((uintptr_t)write_loc)) = time;
193         memcpy(write_loc + stamp_size, data, size);
194
195         _size += stamp_size + size;
196         _silent = false;
197
198         return true;
199 }
200
201 bool
202 MidiBuffer::insert_event(const Evoral::MIDIEvent<TimeType>& ev)
203 {
204         if (size() == 0) {
205                 return push_back(ev);
206         }
207
208         const size_t stamp_size = sizeof(TimeType);
209         const size_t bytes_to_merge = stamp_size + ev.size();
210
211         if (_size + bytes_to_merge >= _capacity) {
212                 cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
213                 PBD::stacktrace (cerr, 20);
214                 return false;
215         }
216
217         TimeType t = ev.time();
218
219         ssize_t insert_offset = -1;
220         for (MidiBuffer::iterator m = begin(); m != end(); ++m) {
221                 if ((*m).time() < t) {
222                         continue;
223                 }
224                 if ((*m).time() == t) {
225                         const uint8_t our_midi_status_byte = *(_data + m.offset + sizeof (TimeType));
226                         if (second_simultaneous_midi_byte_is_first (ev.type(), our_midi_status_byte)) {
227                                 continue;
228                         }
229                 }
230                 insert_offset = m.offset;
231                 break;
232         }
233         if (insert_offset == -1) {
234                 return push_back(ev);
235         }
236
237         // don't use memmove - it may use malloc(!)
238         // memmove (_data + insert_offset + bytes_to_merge, _data + insert_offset, _size - insert_offset);
239         for (ssize_t a = _size + bytes_to_merge - 1, b = _size - 1; b >= insert_offset; --b, --a) {
240                 _data[a] = _data[b];
241         }
242
243         uint8_t* const write_loc = _data + insert_offset;
244         *(reinterpret_cast<TimeType*>((uintptr_t)write_loc)) = t;
245         memcpy(write_loc + stamp_size, ev.buffer(), ev.size());
246
247         _size += bytes_to_merge;
248
249         return true;
250 }
251
252 uint32_t
253 MidiBuffer::write(TimeType time, Evoral::EventType type, uint32_t size, const uint8_t* buf)
254 {
255         insert_event(Evoral::MIDIEvent<TimeType>(type, time, size, const_cast<uint8_t*>(buf)));
256         return size;
257 }
258
259 /** Reserve space for a new event in the buffer.
260  *
261  * This call is for copying MIDI directly into the buffer, the data location
262  * (of sufficient size to write \a size bytes) is returned, or 0 on failure.
263  * This call MUST be immediately followed by a write to the returned data
264  * location, or the buffer will be corrupted and very nasty things will happen.
265  */
266 uint8_t*
267 MidiBuffer::reserve(TimeType time, size_t size)
268 {
269         const size_t stamp_size = sizeof(TimeType);
270         if (_size + stamp_size + size >= _capacity) {
271                 return 0;
272         }
273
274         // write timestamp
275         uint8_t* write_loc = _data + _size;
276         *(reinterpret_cast<TimeType*>((uintptr_t)write_loc)) = time;
277
278         // move write_loc to begin of MIDI buffer data to write to
279         write_loc += stamp_size;
280
281         _size += stamp_size + size;
282         _silent = false;
283
284         return write_loc;
285 }
286
287
288 void
289 MidiBuffer::silence (framecnt_t /*nframes*/, framecnt_t /*offset*/)
290 {
291         /* XXX iterate over existing events, find all in range given by offset & nframes,
292            and delete them.
293         */
294
295         _size = 0;
296         _silent = true;
297 }
298
299 bool
300 MidiBuffer::second_simultaneous_midi_byte_is_first (uint8_t a, uint8_t b)
301 {
302         bool b_first = false;
303
304         /* two events at identical times. we need to determine
305            the order in which they should occur.
306
307            the rule is:
308
309            Controller messages
310            Program Change
311            Note Off
312            Note On
313            Note Pressure
314            Channel Pressure
315            Pitch Bend
316         */
317
318         if ((a) >= 0xf0 || (b) >= 0xf0 || ((a & 0xf) != (b & 0xf))) {
319
320                 /* if either message is not a channel message, or if the channels are
321                  * different, we don't care about the type.
322                  */
323
324                 b_first = true;
325
326         } else {
327
328                 switch (b & 0xf0) {
329                 case MIDI_CMD_CONTROL:
330                         b_first = true;
331                         break;
332
333                 case MIDI_CMD_PGM_CHANGE:
334                         switch (a & 0xf0) {
335                         case MIDI_CMD_CONTROL:
336                                 break;
337                         case MIDI_CMD_PGM_CHANGE:
338                         case MIDI_CMD_NOTE_OFF:
339                         case MIDI_CMD_NOTE_ON:
340                         case MIDI_CMD_NOTE_PRESSURE:
341                         case MIDI_CMD_CHANNEL_PRESSURE:
342                         case MIDI_CMD_BENDER:
343                                 b_first = true;
344                         }
345                         break;
346
347                 case MIDI_CMD_NOTE_OFF:
348                         switch (a & 0xf0) {
349                         case MIDI_CMD_CONTROL:
350                         case MIDI_CMD_PGM_CHANGE:
351                                 break;
352                         case MIDI_CMD_NOTE_OFF:
353                         case MIDI_CMD_NOTE_ON:
354                         case MIDI_CMD_NOTE_PRESSURE:
355                         case MIDI_CMD_CHANNEL_PRESSURE:
356                         case MIDI_CMD_BENDER:
357                                 b_first = true;
358                         }
359                         break;
360
361                 case MIDI_CMD_NOTE_ON:
362                         switch (a & 0xf0) {
363                         case MIDI_CMD_CONTROL:
364                         case MIDI_CMD_PGM_CHANGE:
365                         case MIDI_CMD_NOTE_OFF:
366                                 break;
367                         case MIDI_CMD_NOTE_ON:
368                         case MIDI_CMD_NOTE_PRESSURE:
369                         case MIDI_CMD_CHANNEL_PRESSURE:
370                         case MIDI_CMD_BENDER:
371                                 b_first = true;
372                         }
373                         break;
374                 case MIDI_CMD_NOTE_PRESSURE:
375                         switch (a & 0xf0) {
376                         case MIDI_CMD_CONTROL:
377                         case MIDI_CMD_PGM_CHANGE:
378                         case MIDI_CMD_NOTE_OFF:
379                         case MIDI_CMD_NOTE_ON:
380                                 break;
381                         case MIDI_CMD_NOTE_PRESSURE:
382                         case MIDI_CMD_CHANNEL_PRESSURE:
383                         case MIDI_CMD_BENDER:
384                                 b_first = true;
385                         }
386                         break;
387
388                 case MIDI_CMD_CHANNEL_PRESSURE:
389                         switch (a & 0xf0) {
390                         case MIDI_CMD_CONTROL:
391                         case MIDI_CMD_PGM_CHANGE:
392                         case MIDI_CMD_NOTE_OFF:
393                         case MIDI_CMD_NOTE_ON:
394                         case MIDI_CMD_NOTE_PRESSURE:
395                                 break;
396                         case MIDI_CMD_CHANNEL_PRESSURE:
397                         case MIDI_CMD_BENDER:
398                                 b_first = true;
399                         }
400                         break;
401                 case MIDI_CMD_BENDER:
402                         switch (a & 0xf0) {
403                         case MIDI_CMD_CONTROL:
404                         case MIDI_CMD_PGM_CHANGE:
405                         case MIDI_CMD_NOTE_OFF:
406                         case MIDI_CMD_NOTE_ON:
407                         case MIDI_CMD_NOTE_PRESSURE:
408                         case MIDI_CMD_CHANNEL_PRESSURE:
409                                 break;
410                         case MIDI_CMD_BENDER:
411                                 b_first = true;
412                         }
413                         break;
414                 }
415         }
416
417         return b_first;
418 }
419
420 /** Merge \a other into this buffer.  Realtime safe. */
421 bool
422 MidiBuffer::merge_in_place (const MidiBuffer &other)
423 {
424         if (other.size() && size()) {
425                 DEBUG_TRACE (DEBUG::MidiIO, string_compose ("merge in place, sizes %1/%2\n", size(), other.size()));
426         }
427
428         if (other.size() == 0) {
429                 return true;
430         }
431
432         if (size() == 0) {
433                 copy (other);
434                 return true;
435         }
436
437         if (size() + other.size() > _capacity) {
438                 return false;
439         }
440
441         const_iterator them = other.begin();
442         iterator us = begin();
443
444         while (them != other.end()) {
445
446                 size_t bytes_to_merge;
447                 ssize_t merge_offset;
448
449                 /* gather up total size of events that are earlier than
450                    the event referenced by "us"
451                 */
452
453                 merge_offset = -1;
454                 bytes_to_merge = 0;
455
456                 while (them != other.end() && (*them).time() < (*us).time()) {
457                         if (merge_offset == -1) {
458                                 merge_offset = them.offset;
459                         }
460                         bytes_to_merge += sizeof (TimeType) + (*them).size();
461                         ++them;
462                 }
463
464                 /* "them" now points to either:
465                  *
466                  * 1) an event that has the same or later timestamp than the
467                  *        event pointed to by "us"
468                  *
469                  * OR
470                  *
471                  * 2) the end of the "other" buffer
472                  *
473                  * if "sz" is non-zero, there is data to be merged from "other"
474                  * into this buffer before we do anything else, corresponding
475                  * to the events from "other" that we skipped while advancing
476                  * "them".
477                  */
478
479                 if (bytes_to_merge) {
480                         assert(merge_offset >= 0);
481                         /* move existing */
482                         memmove (_data + us.offset + bytes_to_merge, _data + us.offset, _size - us.offset);
483                         /* increase _size */
484                         _size += bytes_to_merge;
485                         assert (_size <= _capacity);
486                         /* insert new stuff */
487                         memcpy  (_data + us.offset, other._data + merge_offset, bytes_to_merge);
488                         /* update iterator to our own events. this is a miserable hack */
489                         us.offset += bytes_to_merge;
490                 }
491
492                 /* if we're at the end of the other buffer, we're done */
493
494                 if (them == other.end()) {
495                         break;
496                 }
497
498                 /* if we have two messages messages with the same timestamp. we
499                  * must order them correctly.
500                  */
501
502                 if ((*us).time() == (*them).time()) {
503
504                         DEBUG_TRACE (DEBUG::MidiIO,
505                                      string_compose ("simultaneous MIDI events discovered during merge, times %1/%2 status %3/%4\n",
506                                                      (*us).time(), (*them).time(),
507                                                      (int) *(_data + us.offset + sizeof (TimeType)),
508                                                      (int) *(other._data + them.offset + sizeof (TimeType))));
509
510                         uint8_t our_midi_status_byte = *(_data + us.offset + sizeof (TimeType));
511                         uint8_t their_midi_status_byte = *(other._data + them.offset + sizeof (TimeType));
512                         bool them_first = second_simultaneous_midi_byte_is_first (our_midi_status_byte, their_midi_status_byte);
513
514                         DEBUG_TRACE (DEBUG::MidiIO, string_compose ("other message came first ? %1\n", them_first));
515
516                         if (!them_first) {
517                                 /* skip past our own event */
518                                 ++us;
519                         }
520
521                         bytes_to_merge = sizeof (TimeType) + (*them).size();
522
523                         /* move our remaining events later in the buffer by
524                          * enough to fit the one message we're going to merge
525                          */
526
527                         memmove (_data + us.offset + bytes_to_merge, _data + us.offset, _size - us.offset);
528                         /* increase _size */
529                         _size += bytes_to_merge;
530                         assert(_size <= _capacity);
531                         /* insert new stuff */
532                         memcpy  (_data + us.offset, other._data + them.offset, bytes_to_merge);
533                         /* update iterator to our own events. this is a miserable hack */
534                         us.offset += bytes_to_merge;
535                         /* 'us' is now an iterator to the event right after the
536                            new ones that we merged
537                         */
538                         if (them_first) {
539                                 /* need to skip the event pointed to by 'us'
540                                    since its at the same time as 'them'
541                                    (still), and we'll enter
542                                 */
543
544                                 if (us != end()) {
545                                         ++us;
546                                 }
547                         }
548
549                         /* we merged one event from the other buffer, so
550                          * advance the iterator there.
551                          */
552
553                         ++them;
554
555                 } else {
556
557                         /* advance past our own events to get to the correct insertion
558                            point for the next event(s) from "other"
559                         */
560
561                         while (us != end() && (*us).time() <= (*them).time()) {
562                                 ++us;
563                         }
564                 }
565
566                 /* check to see if we reached the end of this buffer while
567                  * looking for the insertion point.
568                  */
569
570                 if (us == end()) {
571
572                         /* just append the rest of other and we're done*/
573
574                         memcpy (_data + us.offset, other._data + them.offset, other._size - them.offset);
575                         _size += other._size - them.offset;
576                         assert(_size <= _capacity);
577                         break;
578                 }
579         }
580
581         return true;
582 }
583