diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
commit | 145364a8af6a1fec06556221e66d4b724a62fc9a (patch) | |
tree | 53bd71a544008c518034f208d64c932dc2883f50 /src/base/CompositionTimeSliceAdapter.cpp | |
download | rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip |
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/base/CompositionTimeSliceAdapter.cpp')
-rw-r--r-- | src/base/CompositionTimeSliceAdapter.cpp | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/src/base/CompositionTimeSliceAdapter.cpp b/src/base/CompositionTimeSliceAdapter.cpp new file mode 100644 index 0000000..b91b804 --- /dev/null +++ b/src/base/CompositionTimeSliceAdapter.cpp @@ -0,0 +1,283 @@ +// -*- c-basic-offset: 4 -*- + +/* + Rosegarden + A sequencer and musical notation editor. + + This program is Copyright 2000-2008 + Guillaume Laurent <glaurent@telegraph-road.org>, + Chris Cannam <cannam@all-day-breakfast.com>, + Richard Bown <bownie@bownie.com> + + This file is Copyright 2002 + Randall Farmer <rfarme@simons-rock.edu> + with additional work by Chris Cannam. + + The moral right of the authors to claim authorship of this work + has been asserted. + + 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 the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +// !!!TODO: handle timeslices + +#include <list> +#include <utility> + +#include "CompositionTimeSliceAdapter.h" +#include "Segment.h" +#include "Composition.h" +#include "Selection.h" + +namespace Rosegarden { + +using std::list; +using std::pair; + +CompositionTimeSliceAdapter::CompositionTimeSliceAdapter(Composition *c, + timeT begin, + timeT end) : + m_composition(c), + m_begin(begin), + m_end(end) +{ + if (begin == end) { + m_begin = 0; + m_end = c->getDuration(); + } + + for (Composition::iterator ci = m_composition->begin(); + ci != m_composition->end(); ++ci) { + m_segmentList.push_back(*ci); + } +} + +CompositionTimeSliceAdapter::CompositionTimeSliceAdapter(Composition *c, + SegmentSelection* s, + timeT begin, + timeT end) : + m_composition(c), + m_begin(begin), + m_end(end) +{ + if (begin == end) { + m_begin = 0; + m_end = c->getDuration(); + } + + for (Composition::iterator ci = m_composition->begin(); + ci != m_composition->end(); ++ci) { + if (!s || s->find(*ci) != s->end()) { + m_segmentList.push_back(*ci); + } + } +} + +CompositionTimeSliceAdapter::CompositionTimeSliceAdapter(Composition *c, + const TrackSet &trackIDs, + timeT begin, + timeT end) : + m_composition(c), + m_begin(begin), + m_end(end) +{ + if (begin == end) { + m_begin = 0; + m_end = c->getDuration(); + } + + for (Composition::iterator ci = m_composition->begin(); + ci != m_composition->end(); ++ci) { + if (trackIDs.find((*ci)->getTrack()) != trackIDs.end()) { + m_segmentList.push_back(*ci); + } + } +} + +CompositionTimeSliceAdapter::iterator +CompositionTimeSliceAdapter::begin() const +{ + if (m_beginItr.m_a == 0) { + m_beginItr = iterator(this); + fill(m_beginItr, false); + } + return m_beginItr; +} + +CompositionTimeSliceAdapter::iterator +CompositionTimeSliceAdapter::end() const +{ + return iterator(this); +} + +void +CompositionTimeSliceAdapter::fill(iterator &i, bool atEnd) const +{ + // The segment iterators should all point to events starting at or + // after m_begin (if atEnd false) or at or before m_end (if atEnd true). + + for (unsigned int k = 0; k < m_segmentList.size(); ++k) { + Segment::iterator j = m_segmentList[k]->findTime(atEnd ? m_end : m_begin); + i.m_segmentItrList.push_back(j); + } + + // fill m_curEvent & m_curTrack + if (!atEnd) ++i; +} + +CompositionTimeSliceAdapter::iterator& +CompositionTimeSliceAdapter::iterator::operator=(const iterator &i) +{ + if (&i == this) return *this; + m_segmentItrList.clear(); + + for (segmentitrlist::const_iterator j = i.m_segmentItrList.begin(); + j != i.m_segmentItrList.end(); ++j) { + m_segmentItrList.push_back(Segment::iterator(*j)); + } + + m_a = i.m_a; + m_curTrack = i.m_curTrack; + m_curEvent = i.m_curEvent; + m_needFill = i.m_needFill; + return *this; +} + +CompositionTimeSliceAdapter::iterator::iterator(const iterator &i) : + m_a(i.m_a), + m_curEvent(i.m_curEvent), + m_curTrack(i.m_curTrack), + m_needFill(i.m_needFill) +{ + for (segmentitrlist::const_iterator j = i.m_segmentItrList.begin(); + j != i.m_segmentItrList.end(); ++j) { + m_segmentItrList.push_back(Segment::iterator(*j)); + } +} + +CompositionTimeSliceAdapter::iterator& +CompositionTimeSliceAdapter::iterator::operator++() +{ + assert(m_a != 0); + + // needFill is only set true for iterators created at end() + if (m_needFill) { + m_a->fill(*this, true); + m_needFill = false; + } + + Event *e = 0; + unsigned int pos = 0; + + for (unsigned int i = 0; i < m_a->m_segmentList.size(); ++i) { + + if (!m_a->m_segmentList[i]->isBeforeEndMarker(m_segmentItrList[i])) continue; + + if (!e || strictLessThan(*m_segmentItrList[i], e)) { + e = *m_segmentItrList[i]; + m_curTrack = m_a->m_segmentList[i]->getTrack(); + pos = i; + } + } + + // Check whether we're past the end time, if there is one + if (!e || e->getAbsoluteTime() >= m_a->m_end) { + m_curEvent = 0; + m_curTrack = -1; + return *this; + } + + // e is now an Event* less than or equal to any that the iterator + // hasn't already passed over + m_curEvent = e; + + // m_segmentItrList[pos] is a segment::iterator that points to e + ++m_segmentItrList[pos]; + + return *this; +} + +CompositionTimeSliceAdapter::iterator& +CompositionTimeSliceAdapter::iterator::operator--() +{ + assert(m_a != 0); + + // needFill is only set true for iterators created at end() + if (m_needFill) { + m_a->fill(*this, true); + m_needFill = false; + } + + Event *e = 0; + int pos = -1; + + // Decrement is more subtle than increment. We have to scan the + // iterators available, and decrement the one that points to + // m_curEvent. Then to fill m_curEvent we need to find the next + // greatest event back that is not itself m_curEvent. + + for (unsigned int i = 0; i < m_a->m_segmentList.size(); ++i) { + + if (m_segmentItrList[i] == m_a->m_segmentList[i]->begin()) continue; + + Segment::iterator si(m_segmentItrList[i]); + --si; + + if (*si == m_curEvent) { + pos = i; + } else if (!e || !strictLessThan(*si, e)) { + e = *si; + m_curTrack = m_a->m_segmentList[i]->getTrack(); + } + } + + if (e) m_curEvent = e; + if (pos >= 0) { + --m_segmentItrList[pos]; + } + + return *this; +} + +bool +CompositionTimeSliceAdapter::iterator::operator==(const iterator& other) const { + return m_a == other.m_a && m_curEvent == other.m_curEvent; +} + +bool +CompositionTimeSliceAdapter::iterator::operator!=(const iterator& other) const { + return !operator==(other); +} + +Event * +CompositionTimeSliceAdapter::iterator::operator*() const { + return m_curEvent; +} + +Event & +CompositionTimeSliceAdapter::iterator::operator->() const { + return *m_curEvent; +} + +int +CompositionTimeSliceAdapter::iterator::getTrack() const { + return m_curTrack; +} + +bool +CompositionTimeSliceAdapter::iterator::strictLessThan(Event *e1, Event *e2) { + // We need a complete ordering of events -- we can't cope with two events + // comparing equal. i.e. one of e1 < e2 and e2 < e1 must be true. The + // ordering can be arbitrary -- we just compare addresses for events the + // event comparator doesn't distinguish between. We know we're always + // dealing with event pointers, not copies of events. + if (*e1 < *e2) return true; + else if (*e2 < *e1) return false; + else return e1 < e2; +} + +} |