make i18n build work ; add mackie dir back to build ; token work on amp for MIDI...
[ardour.git] / libs / ardour / ardour / midi_buffer.h
index 812f697aa3de32f1765063c12bf47ba2bb09e3e4..d5f15fb6212ba98af4a232e87d664939a88afb35 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2006 Paul Davis 
+    Copyright (C) 2006-2009 Paul Davis 
     Author: Dave Robillard
     
     This program is free software; you can redistribute it and/or modify it
 #ifndef __ardour_midi_buffer_h__
 #define __ardour_midi_buffer_h__
 
-#include <midi++/event.h>
-#include <ardour/buffer.h>
+#include "evoral/midi_util.h"
+#include "midi++/event.h"
+#include "ardour/buffer.h"
+#include "ardour/event_type_map.h"
 
 namespace ARDOUR {
 
@@ -30,45 +32,63 @@ namespace ARDOUR {
 class MidiBuffer : public Buffer
 {
 public:
+       typedef nframes_t TimeType;
+
        MidiBuffer(size_t capacity);
        ~MidiBuffer();
 
-       void silence(nframes_t dur, nframes_t offset=0);
-       
-       void read_from(const Buffer& src, nframes_t nframes, nframes_t offset);
+       void silence (nframes_t nframes, nframes_t offset = 0);
+       void read_from (const Buffer& src, nframes_t nframes, nframes_t dst_offset = 0, nframes_t src_offset = 0);
+       void merge_from (const Buffer& src, nframes_t nframes, nframes_t dst_offset = 0, nframes_t src_offset = 0);
        
        void copy(const MidiBuffer& copy);
 
-       bool     push_back(const Evoral::MIDIEvent& event);
+       bool     push_back(const Evoral::MIDIEvent<TimeType>& event);
        bool     push_back(const jack_midi_event_t& event);
-       uint8_t* reserve(double time, size_t size);
+       bool     push_back(TimeType time, size_t size, const uint8_t* data);
+       uint8_t* reserve(TimeType time, size_t size);
 
        void resize(size_t);
 
        bool merge(const MidiBuffer& a, const MidiBuffer& b);
-       bool merge_in_place( const MidiBuffer &other );
+       bool merge_in_place(const MidiBuffer &other);
        
-       struct iterator {
-               iterator(MidiBuffer& b, size_t i) : buffer(b), index(i) {}
-
-               inline Evoral::MIDIEvent& operator*() const { return buffer[index]; }
-               inline iterator& operator++() { ++index; return *this; } // prefix
-               inline bool operator!=(const iterator& other) const { return index != other.index; }
-               
-               MidiBuffer& buffer;
-               size_t      index;
+       template<typename BufferType, typename EventType>
+       struct iterator_base {
+           iterator_base<BufferType, EventType>(BufferType& b, nframes_t o) : buffer(b), offset(o) {}
+               inline EventType operator*() const {
+                       uint8_t* ev_start = buffer._data + offset + sizeof(TimeType);
+                       int event_size = Evoral::midi_event_size(ev_start);
+                       assert(event_size >= 0);
+                       return EventType(EventTypeMap::instance().midi_event_type(*ev_start),
+                                       *((TimeType*)(buffer._data + offset)),
+                                       event_size, ev_start);
+               }
+               inline EventType operator*() {
+                       uint8_t* ev_start = buffer._data + offset + sizeof(TimeType);
+                       int event_size = Evoral::midi_event_size(ev_start);
+                       assert(event_size >= 0);
+                       return EventType(EventTypeMap::instance().midi_event_type(*ev_start),
+                                       *((TimeType*)(buffer._data + offset)),
+                                       event_size, ev_start);
+               }
+
+               inline iterator_base<BufferType, EventType>& operator++() {
+                       uint8_t* ev_start = buffer._data + offset + sizeof(TimeType);
+                       int event_size = Evoral::midi_event_size(ev_start);
+                       assert(event_size >= 0);
+                       offset += sizeof(TimeType) + event_size;
+                       return *this;
+               }
+               inline bool operator!=(const iterator_base<BufferType, EventType>& other) const {
+                       return (&buffer != &other.buffer) || (offset != other.offset);
+               }
+               BufferType&     buffer;
+               size_t          offset;
        };
        
-       struct const_iterator {
-               const_iterator(const MidiBuffer& b, size_t i) : buffer(b), index(i) {}
-
-               inline const Evoral::MIDIEvent& operator*() const { return buffer[index]; }
-               inline const_iterator& operator++() { ++index; return *this; } // prefix
-               inline bool operator!=(const const_iterator& other) const { return index != other.index; }
-               
-               const MidiBuffer& buffer;
-               size_t            index;
-       };
+       typedef iterator_base< MidiBuffer, Evoral::MIDIEvent<TimeType> >             iterator;
+       typedef iterator_base< const MidiBuffer, const Evoral::MIDIEvent<TimeType> > const_iterator;
 
        iterator begin() { return iterator(*this, 0); }
        iterator end()   { return iterator(*this, _size); }
@@ -77,24 +97,10 @@ public:
        const_iterator end()   const { return const_iterator(*this, _size); }
 
 private:
-
-       friend class iterator;
-       friend class const_iterator;
+       friend class iterator_base< MidiBuffer, Evoral::MIDIEvent<TimeType> >;
+       friend class iterator_base< const MidiBuffer, const Evoral::MIDIEvent<TimeType> >;
        
-       const Evoral::MIDIEvent& operator[](size_t i) const { assert(i < _size); return _events[i]; }
-       Evoral::MIDIEvent& operator[](size_t i) { assert(i < _size); return _events[i]; }
-
-       // FIXME: Eliminate this
-       static const size_t MAX_EVENT_SIZE = 4; // bytes
-       
-       /* We use _size as "number of events", so the size of _data is
-        * (_size * MAX_EVENT_SIZE)
-        */
-
-       /* FIXME: this is utter crap.  rewrite as a flat/packed buffer like MidiRingBuffer */
-
-       Evoral::MIDIEvent* _events; ///< Event structs that point to offsets in _data
-       uint8_t*           _data;   ///< MIDI, straight up.  No time stamps.
+       uint8_t* _data; ///< timestamp, event, timestamp, event, ...
 };