summaryrefslogtreecommitdiffstats
path: root/src/base/CompositionTimeSliceAdapter.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
commit145364a8af6a1fec06556221e66d4b724a62fc9a (patch)
tree53bd71a544008c518034f208d64c932dc2883f50 /src/base/CompositionTimeSliceAdapter.cpp
downloadrosegarden-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.cpp283
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;
+}
+
+}