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 ecb48d9da9bb6fc6c3db4f7284a447774361e02c..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 <ardour/buffer.h>
+#include "evoral/midi_util.h"
+#include "midi++/event.h"
+#include "ardour/buffer.h"
+#include "ardour/event_type_map.h"
 
 namespace ARDOUR {
 
@@ -29,33 +32,75 @@ 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 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<TimeType>& event);
+       bool     push_back(const jack_midi_event_t& event);
+       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);
        
-       void read_from(const Buffer& src, nframes_t nframes, nframes_t offset);
+       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);
+               }
 
-       bool  push_back(const ARDOUR::MidiEvent& event);
-       bool  push_back(const jack_midi_event_t& event);
-       Byte* reserve(double time, size_t size);
+               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;
+       };
        
-       const MidiEvent& operator[](size_t i) const { assert(i < _size); return _events[i]; }
-       MidiEvent& operator[](size_t i) { assert(i < _size); return _events[i]; }
+       typedef iterator_base< MidiBuffer, Evoral::MIDIEvent<TimeType> >             iterator;
+       typedef iterator_base< const MidiBuffer, const Evoral::MIDIEvent<TimeType> > const_iterator;
 
-       static size_t max_event_size() { return MAX_EVENT_SIZE; }
+       iterator begin() { return iterator(*this, 0); }
+       iterator end()   { return iterator(*this, _size); }
+
+       const_iterator begin() const { return const_iterator(*this, 0); }
+       const_iterator end()   const { return const_iterator(*this, _size); }
 
 private:
-       // FIXME: Jack needs to tell us this
-       static const size_t MAX_EVENT_SIZE = 4; // bytes
+       friend class iterator_base< MidiBuffer, Evoral::MIDIEvent<TimeType> >;
+       friend class iterator_base< const MidiBuffer, const Evoral::MIDIEvent<TimeType> >;
        
-       /* We use _size as "number of events", so the size of _data is
-        * (_size * MAX_EVENT_SIZE)
-        */
-
-       MidiEvent* _events; ///< Event structs that point to offsets in _data
-       Byte*      _data;   ///< MIDI, straight up.  No time stamps.
+       uint8_t* _data; ///< timestamp, event, timestamp, event, ...
 };