Templateify MidiBuffer iterators (avoid code duplication since they're about to get less trivial).

Clean up MidiBuffer code.


git-svn-id: svn://localhost/ardour2/branches/3.0@4469 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2009-02-01 03:15:31 +00:00
parent aaa91db6d9
commit e666c8e98f
3 changed files with 38 additions and 47 deletions

View file

@ -46,29 +46,24 @@ public:
void resize(size_t); void resize(size_t);
bool merge(const MidiBuffer& a, const MidiBuffer& b); bool merge(const MidiBuffer& a, const MidiBuffer& b);
bool merge_in_place( const MidiBuffer &other ); bool merge_in_place(const MidiBuffer &other);
struct iterator { template<typename B, typename E>
iterator(MidiBuffer& b, size_t i) : buffer(b), index(i) {} struct iterator_base {
iterator_base<B,E>(B& b, size_t i) : buffer(b), index(i) {}
inline Evoral::MIDIEvent& operator*() const { return buffer[index]; } inline E& operator*() const { return buffer[index]; }
inline iterator& operator++() { ++index; return *this; } // prefix inline iterator_base<B,E>& operator++() { ++index; return *this; } // prefix
inline bool operator!=(const iterator& other) const { return index != other.index; } inline bool operator!=(const iterator_base<B,E>& other) const {
return index != other.index;
}
MidiBuffer& buffer; B& buffer;
size_t index; size_t index;
}; };
struct const_iterator { typedef iterator_base<MidiBuffer, Evoral::MIDIEvent> iterator;
const_iterator(const MidiBuffer& b, size_t i) : buffer(b), index(i) {} typedef iterator_base<const MidiBuffer, const Evoral::MIDIEvent> const_iterator;
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;
};
iterator begin() { return iterator(*this, 0); } iterator begin() { return iterator(*this, 0); }
iterator end() { return iterator(*this, _size); } iterator end() { return iterator(*this, _size); }
@ -78,8 +73,8 @@ public:
private: private:
friend class iterator; friend class iterator_base<MidiBuffer, Evoral::MIDIEvent>;
friend class const_iterator; friend class iterator_base<const MidiBuffer, const Evoral::MIDIEvent>;
const Evoral::MIDIEvent& operator[](size_t i) const { assert(i < _size); return _events[i]; } 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]; } Evoral::MIDIEvent& operator[](size_t i) { assert(i < _size); return _events[i]; }

View file

@ -35,10 +35,9 @@ MidiBuffer::MidiBuffer(size_t capacity)
: Buffer(DataType::MIDI, capacity) : Buffer(DataType::MIDI, capacity)
, _events(0) , _events(0)
, _data(0) , _data(0)
// , _owns_data(false)
{ {
if (capacity) { if (capacity) {
resize (_capacity); resize(_capacity);
silence(_capacity); silence(_capacity);
} }
} }
@ -54,7 +53,7 @@ MidiBuffer::~MidiBuffer()
} }
void void
MidiBuffer::resize (size_t size) MidiBuffer::resize(size_t size)
{ {
assert(size > 0); assert(size > 0);
@ -62,13 +61,8 @@ MidiBuffer::resize (size_t size)
return; return;
} }
if (_data) { free(_data);
free (_data); free(_events);
}
if (_events) {
free (_events);
}
_size = 0; _size = 0;
_capacity = size; _capacity = size;
@ -116,7 +110,7 @@ MidiBuffer::read_from(const Buffer& src, nframes_t nframes, nframes_t offset)
} }
// FIXME: slow // FIXME: slow
for (size_t i=0; i < msrc.size(); ++i) { for (size_t i = 0; i < msrc.size(); ++i) {
const Evoral::MIDIEvent& ev = msrc[i]; const Evoral::MIDIEvent& ev = msrc[i];
//cout << "MidiBuffer::read_from event type: " << int(ev.type()) //cout << "MidiBuffer::read_from event type: " << int(ev.type())
// << " time: " << ev.time() << " buffer size: " << _size << endl; // << " time: " << ev.time() << " buffer size: " << _size << endl;
@ -220,8 +214,9 @@ MidiBuffer::reserve(double time, size_t size)
return 0; return 0;
} }
if (_size == _capacity) if (_size == _capacity) {
return 0; return 0;
}
uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE); uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE);
@ -251,27 +246,28 @@ MidiBuffer::silence(nframes_t dur, nframes_t offset)
} }
bool bool
MidiBuffer::merge_in_place( const MidiBuffer &other ) MidiBuffer::merge_in_place(const MidiBuffer &other)
{ {
if( other.size() == 0 ) if (other.size() == 0) {
return true; return true;
}
if( this->size() == 0 ) { if (this->size() == 0) {
copy( other ); copy(other);
return true; return true;
} }
{ {
MidiBuffer merge_buffer( 0 ); MidiBuffer merge_buffer(0);
Evoral::MIDIEvent onstack_events[_capacity]; Evoral::MIDIEvent onstack_events[_capacity];
uint8_t onstack_data[_capacity * MAX_EVENT_SIZE]; uint8_t onstack_data[_capacity * MAX_EVENT_SIZE];
merge_buffer._events = onstack_events; merge_buffer._events = onstack_events;
merge_buffer._data = onstack_data; merge_buffer._data = onstack_data;
merge_buffer._size = 0; merge_buffer._size = 0;
bool retval = merge_buffer.merge( *this, other ); bool retval = merge_buffer.merge(*this, other);
copy( merge_buffer ); copy(merge_buffer);
// set pointers to zero again, so destructor // set pointers to zero again, so destructor
// does not end in calling free() for memory // does not end in calling free() for memory
@ -294,12 +290,13 @@ MidiBuffer::merge(const MidiBuffer& a, const MidiBuffer& b)
{ {
_size = 0; _size = 0;
// This is mostly the case :( if (this == &a) {
if( this == &a ) merge_in_place(b);
merge_in_place( b ); }
if( this == &b ) if (this == &b) {
merge_in_place( a ); merge_in_place(a);
}
size_t a_index = 0; size_t a_index = 0;
size_t b_index = 0; size_t b_index = 0;

View file

@ -1,6 +1,5 @@
/* /*
Copyright (C) 2007 Paul Davis Copyright (C) 2007 Paul Davis
Author: Dave Robillard
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by