summaryrefslogtreecommitdiff
path: root/muse2/muse/part.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/part.cpp')
-rw-r--r--muse2/muse/part.cpp743
1 files changed, 169 insertions, 574 deletions
diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp
index 5f3aa8ee..1d246c50 100644
--- a/muse2/muse/part.cpp
+++ b/muse2/muse/part.cpp
@@ -22,6 +22,7 @@
//
//=========================================================
+#include <assert.h>
#include <stdio.h>
#include <cmath>
@@ -39,316 +40,97 @@ namespace MusECore {
int Part::snGen=0;
-//---------------------------------------------------------
-// unchainClone
-//---------------------------------------------------------
-void unchainClone(Part* p)
+void Part::unchainClone()
{
- chainCheckErr(p);
+ chainCheckErr(this); // FIXME proper assert!
- // Unchain the part.
- p->prevClone()->setNextClone(p->nextClone());
- p->nextClone()->setPrevClone(p->prevClone());
+ if (_backupClone) printf("THIS SHOULD NEVER HAPPEN: Part::unchainClone() called, but _backupClone was non-NULL\n");
- // Isolate the part.
- p->setPrevClone(p);
- p->setNextClone(p);
-}
-
-//---------------------------------------------------------
-// chainClone
-// The quick way - if part to chain to is known...
-//---------------------------------------------------------
-
-void chainClone(Part* p1, Part* p2)
-{
- chainCheckErr(p1);
+ _backupClone=_prevClone;
- // Make sure the part to be chained is unchained first.
- p2->prevClone()->setNextClone(p2->nextClone());
- p2->nextClone()->setPrevClone(p2->prevClone());
+ // Unchain the part.
+ _prevClone->_nextClone = _nextClone;
+ _nextClone->_prevClone = _prevClone;
- // Link the part to be chained.
- p2->setPrevClone(p1);
- p2->setNextClone(p1->nextClone());
+ // Isolate the part.
+ _prevClone = this;
+ _nextClone = this;
- // Re-link the existing part.
- p1->nextClone()->setPrevClone(p2);
- p1->setNextClone(p2);
+ _clonemaster_sn = this->_sn;
}
-//---------------------------------------------------------
-// chainCloneInternal
-// No error check, so it can be called by replaceClone()
-//---------------------------------------------------------
-
-void chainCloneInternal(Part* p)
+void Part::chainClone(Part* p)
{
- Track* t = p->track();
- Part* p1 = 0;
+ // FIXME assertion
+ assert(p);
- // Look for a part with the same event list, that we can chain to.
- // It's faster if track type is known...
-
- if(!t || (t && t->isMidiTrack()))
+ if (! (_prevClone==this && _nextClone==this)) // the part is still part of a clone chain!
{
- MidiTrack* mt = 0;
- MidiTrackList* mtl = MusEGlobal::song->midis();
- for(ciMidiTrack imt = mtl->begin(); imt != mtl->end(); ++imt)
- {
- mt = *imt;
- const PartList* pl = mt->cparts();
- for(ciPart ip = pl->begin(); ip != pl->end(); ++ip)
- {
- if(ip->second != p && ip->second->cevents() == p->cevents())
- {
- p1 = ip->second;
- break;
- }
- }
- // If a suitable part was found on a different track, we're done. We will chain to it.
- // Otherwise keep looking for parts on another track. If no others found, then we
- // chain to any suitable part which was found on the same given track t.
- if(p1 && mt != t)
- break;
- }
- }
- if((!p1 && !t) || (t && t->type() == Track::WAVE))
- {
- MusECore::WaveTrack* wt = 0;
- MusECore::WaveTrackList* wtl = MusEGlobal::song->waves();
- for(MusECore::ciWaveTrack iwt = wtl->begin(); iwt != wtl->end(); ++iwt)
- {
- wt = *iwt;
- const PartList* pl = wt->cparts();
- for(ciPart ip = pl->begin(); ip != pl->end(); ++ip)
- {
- if(ip->second != p && ip->second->cevents() == p->cevents())
- {
- p1 = ip->second;
- break;
- }
- }
- if(p1 && wt != t)
- break;
- }
+ printf("ERROR: THIS SHOULD NEVER HAPPEN: Part::chainClone() called, but part is already chained! I'll unchain for now, but better fix that!\n");
+ this->unchainClone();
}
+
+ // Make our links to the chain
+ this->_prevClone = p;
+ this->_nextClone = p->_nextClone;
- // No part found with same event list? Done.
- if(!p1)
- return;
-
- // Make sure the part to be chained is unchained first.
- p->prevClone()->setNextClone(p->nextClone());
- p->nextClone()->setPrevClone(p->prevClone());
+ // Make the chain's links to us
+ this->_nextClone->_prevClone = this;
+ p->_nextClone = this;
- // Link the part to be chained.
- p->setPrevClone(p1);
- p->setNextClone(p1->nextClone());
+ // we only chain clones. we must trust in the GUI thread that the eventlist is consistent.
- // Re-link the existing part.
- p1->nextClone()->setPrevClone(p);
- p1->setNextClone(p);
+ this->_clonemaster_sn = p->_sn;
}
-//---------------------------------------------------------
-// chainClone
-// The slow way - if part to chain to is not known...
-//---------------------------------------------------------
-
-void chainClone(Part* p)
+void Part::rechainClone()
{
- chainCheckErr(p);
- chainCloneInternal(p);
+ if(_backupClone)
+ {
+ this->chainClone(_backupClone);
+ _backupClone = NULL;
+ }
}
-//---------------------------------------------------------
-// replaceClone
-//---------------------------------------------------------
+bool Part::isCloneOf(const Part* other) const
+{
+ return this->_clonemaster_sn == other->_clonemaster_sn;
+}
-// this replaces p1 by p2. p1 is isolated, and p2 takes its place instead.
-void replaceClone(Part* p1, Part* p2)
+int Part::nClones() const
{
- chainCheckErr(p1);
-
- // Make sure the replacement part is unchained first.
- p2->prevClone()->setNextClone(p2->nextClone());
- p2->nextClone()->setPrevClone(p2->prevClone());
-
- // If the two parts share the same event list, then this MUST
- // be a straight forward replacement operation. Continue on.
- // If not, and either part has more than one ref count, then do this...
- if(p1->cevents() != p2->cevents())
- {
- bool ret = false;
- // If the part to be replaced is a single uncloned part, [DELETETHIS 4 this seems outdated=wrong to me]
- // and the replacement part is not, then this operation
- // MUST be an undo of a de-cloning of a cloned part.
- //if(p1->cevents()->refCount() <= 1 && p2->cevents()->refCount() > 1)
- if(p2->cevents()->refCount() > 1)
- {
- // Chain the replacement part. We don't know the chain it came from,
- // so we use the slow method.
- chainCloneInternal(p2);
- //return; DELETETHIS
- ret = true;
- }
-
- // If the replacement part is a single uncloned part, DELETETHIS same as above
- // and the part to be replaced is not, then this operation
- // MUST be a de-cloning of a cloned part.
- //if(p1->cevents()->refCount() > 1 && p2->cevents()->refCount() <= 1)
- if(p1->cevents()->refCount() > 1)
- {
- // Unchain the part to be replaced.
- p1->prevClone()->setNextClone(p1->nextClone());
- p1->nextClone()->setPrevClone(p1->prevClone());
- // Isolate the part.
- p1->setPrevClone(p1);
- p1->setNextClone(p1);
- ret = true;
- }
-
- // Was the operation handled?
- if(ret)
- return;
- // Note that two parts here with different event lists, each with more than one
- // reference count, would be an error. It's not done anywhere in muse. But just
- // to be sure, four lines above were changed to allow that condition.
- // If each of the two different event lists, has only one ref count, we
- // handle it like a regular replacement, below...
- }
-
- // If the part to be replaced is a clone not a single lone part, re-link its neighbours to the replacement part...
- if(p1->prevClone() != p1)
- {
- p1->prevClone()->setNextClone(p2);
- p2->setPrevClone(p1->prevClone());
- }
- else
- p2->setPrevClone(p2);
-
- if(p1->nextClone() != p1)
- {
- p1->nextClone()->setPrevClone(p2);
- p2->setNextClone(p1->nextClone());
- }
- else
- p2->setNextClone(p2);
-
- // Isolate the replaced part.
- p1->setNextClone(p1);
- p1->setPrevClone(p1);
+ int n=1;
+
+ for(const Part* it = this->_nextClone; it!=this; it=it->_nextClone)
+ n++;
+
+ return n;
}
+
+// FIXME FINDMICHJETZT TODO: weg damit!
+
//---------------------------------------------------------
// unchainTrackParts
//---------------------------------------------------------
-void unchainTrackParts(Track* t, bool decRefCount)
+void unchainTrackParts(Track* t)
{
PartList* pl = t->parts();
for(iPart ip = pl->begin(); ip != pl->end(); ++ip)
- {
- Part* p = ip->second;
- chainCheckErr(p);
-
- // Do we want to decrease the reference count?
- if(decRefCount)
- p->events()->incARef(-1);
-
- // Unchain the part.
- p->prevClone()->setNextClone(p->nextClone());
- p->nextClone()->setPrevClone(p->prevClone());
-
- // Isolate the part.
- p->setPrevClone(p);
- p->setNextClone(p);
- }
+ ip->second->unchainClone();
}
//---------------------------------------------------------
// chainTrackParts
//---------------------------------------------------------
-void chainTrackParts(Track* t, bool incRefCount)
+void chainTrackParts(Track* t)
{
PartList* pl = t->parts();
- for(iPart ip = pl->begin(); ip != pl->end(); ++ip)
- {
- Part* p = ip->second;
- chainCheckErr(p);
-
- // Do we want to increase the reference count?
- if(incRefCount)
- p->events()->incARef(1);
-
- Part* p1 = 0;
-
- // Look for a part with the same event list, that we can chain to.
- // It's faster if track type is known...
-
- if(!t || (t && t->isMidiTrack()))
- {
- MidiTrack* mt = 0;
- MidiTrackList* mtl = MusEGlobal::song->midis();
- for(ciMidiTrack imt = mtl->begin(); imt != mtl->end(); ++imt)
- {
- mt = *imt;
- const PartList* pl = mt->cparts();
- for(ciPart ip = pl->begin(); ip != pl->end(); ++ip)
- {
- if(ip->second != p && ip->second->cevents() == p->cevents())
- {
- p1 = ip->second;
- break;
- }
- }
- // If a suitable part was found on a different track, we're done. We will chain to it.
- // Otherwise keep looking for parts on another track. If no others found, then we
- // chain to any suitable part which was found on the same given track t.
- if(p1 && mt != t)
- break;
- }
- }
- if((!p1 && !t) || (t && t->type() == Track::WAVE))
- {
- MusECore::WaveTrack* wt = 0;
- MusECore::WaveTrackList* wtl = MusEGlobal::song->waves();
- for(MusECore::ciWaveTrack iwt = wtl->begin(); iwt != wtl->end(); ++iwt)
- {
- wt = *iwt;
- const PartList* pl = wt->cparts();
- for(ciPart ip = pl->begin(); ip != pl->end(); ++ip)
- {
- if(ip->second != p && ip->second->cevents() == p->cevents())
- {
- p1 = ip->second;
- break;
- }
- }
- if(p1 && wt != t)
- break;
- }
- }
-
- // No part found with same event list? Done.
- if(!p1)
- continue;
-
- // Make sure the part to be chained is unchained first.
- p->prevClone()->setNextClone(p->nextClone());
- p->nextClone()->setPrevClone(p->prevClone());
-
- // Link the part to be chained.
- p->setPrevClone(p1);
- p->setNextClone(p1->nextClone());
-
- // Re-link the existing part.
- p1->nextClone()->setPrevClone(p);
- p1->setNextClone(p);
- }
+ for(riPart ip = pl->rbegin(); ip != pl->rend(); ++ip) // walk through in opposite direction than we unchained them.
+ ip->second->rechainClone();
}
//---------------------------------------------------------
@@ -372,8 +154,6 @@ void addPortCtrlEvents(Event& event, Part* part, bool doClones)
{
// Traverse and process the clone chain ring until we arrive at the same part again.
// The loop is a safety net.
- // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents,
- // we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.
Part* p = part;
while(1)
{
@@ -434,8 +214,6 @@ void addPortCtrlEvents(Part* part, bool doClones)
{
// Traverse and process the clone chain ring until we arrive at the same part again.
// The loop is a safety net.
- // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents,
- // we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.
Part* p = part;
while(1)
{
@@ -445,9 +223,8 @@ void addPortCtrlEvents(Part* part, bool doClones)
MidiTrack* mt = (MidiTrack*)t;
MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
int ch = mt->outChannel();
- const EventList* el = p->cevents();
unsigned len = p->lenTick();
- for(ciEvent ie = el->begin(); ie != el->end(); ++ie)
+ for(ciEvent ie = p->events().begin(); ie != p->events().end(); ++ie)
{
const Event& ev = ie->second;
// Added by T356. Do not add events which are past the end of the part.
@@ -499,8 +276,6 @@ void removePortCtrlEvents(Event& event, Part* part, bool doClones)
{
// Traverse and process the clone chain ring until we arrive at the same part again.
// The loop is a safety net.
- // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents,
- // we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.
Part* p = part;
while(1)
{
@@ -555,8 +330,6 @@ void removePortCtrlEvents(Part* part, bool doClones)
{
// Traverse and process the clone chain ring until we arrive at the same part again.
// The loop is a safety net.
- // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents,
- // we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain.
Part* p = part;
while(1)
{
@@ -566,16 +339,9 @@ void removePortCtrlEvents(Part* part, bool doClones)
MidiTrack* mt = (MidiTrack*)t;
MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
int ch = mt->outChannel();
- const EventList* el = p->cevents();
- //unsigned len = p->lenTick();
- for(ciEvent ie = el->begin(); ie != el->end(); ++ie)
+ for(ciEvent ie = p->events().begin(); ie != p->events().end(); ++ie)
{
const Event& ev = ie->second;
- // Added by T356. Do not remove events which are past the end of the part. DELETETHIS 5
- // No, actually, do remove ALL of them belonging to the part.
- // Just in case there are stray values left after the part end.
- //if(ev.tick() >= len)
- // break;
if(ev.type() == Controller)
{
@@ -620,17 +386,18 @@ void removePortCtrlEvents(Part* part, bool doClones)
iEvent Part::addEvent(Event& p)
{
- return _events->add(p);
+ assert(!hasClones());
+ return _events.add(p);
}
//---------------------------------------------------------
// index
//---------------------------------------------------------
-int PartList::index(Part* part)
+int PartList::index(const Part* part) const
{
int index = 0;
- for (iPart i = begin(); i != end(); ++i, ++index)
+ for (ciPart i = begin(); i != end(); ++i, ++index)
if (i->second == part) {
return index;
}
@@ -652,65 +419,81 @@ Part* PartList::find(int idx)
return 0;
}
-//---------------------------------------------------------
-// Part
-//---------------------------------------------------------
-
-Part::Part(const Part& p) : PosLen(p)
-{
- _sn=p._sn;
- _name=p._name;
- _selected=p._selected;
- _mute=p._mute;
- _colorIndex=p._colorIndex;
- _hiddenEvents=p._hiddenEvents;
- _track=p._track;
- _events=p._events;
- _prevClone=p._prevClone;
- _nextClone=p._nextClone;
-
- _events->incRef(1);
-}
-
Part::Part(Track* t)
{
_hiddenEvents = NoEventsHidden;
_prevClone = this;
_nextClone = this;
- setSn(newSn());
+ _backupClone = NULL;
+ _sn = newSn();
+ _clonemaster_sn = _sn;
_track = t;
_selected = false;
_mute = false;
_colorIndex = 0;
- _events = new EventList;
- _events->incRef(1);
- _events->incARef(1);
}
-Part::Part(Track* t, EventList* ev)
- {
- _hiddenEvents = NoEventsHidden;
- _prevClone = this;
- _nextClone = this;
- setSn(newSn());
- _track = t;
- _selected = false;
- _mute = false;
- _colorIndex = 0;
- _events = ev;
- _events->incRef(1);
- _events->incARef(1);
- }
+WavePart* WavePart::duplicateEmpty() const
+{
+ WavePart* part = new WavePart((WaveTrack*)this->_track);
+ part->setName(name());
+ part->setColorIndex(colorIndex());
+
+ *(PosLen*)part = *(PosLen*)this;
+ part->setMute(mute());
+
+ return part;
+}
-//---------------------------------------------------------
-// MidiPart
-// copy constructor
-//---------------------------------------------------------
+WavePart* WavePart::duplicate() const
+{
+ return (WavePart*)Part::duplicate();
+}
-MidiPart::MidiPart(const MidiPart& p) : Part(p)
+WavePart* WavePart::createNewClone() const
{
- _prevClone = this;
- _nextClone = this;
+ return (WavePart*)Part::createNewClone();
+}
+
+MidiPart* MidiPart::duplicateEmpty() const
+{
+ MidiPart* part = new MidiPart((MidiTrack*)this->_track);
+ part->setName(name());
+ part->setColorIndex(colorIndex());
+
+ *(PosLen*)part = *(PosLen*)this;
+ part->setMute(mute());
+
+ return part;
+}
+
+MidiPart* MidiPart::duplicate() const
+{
+ return (MidiPart*)Part::duplicate();
+}
+
+MidiPart* MidiPart::createNewClone() const
+{
+ return (MidiPart*)Part::createNewClone();
+}
+
+
+Part* Part::createNewClone() const
+{
+ Part* clone = duplicate();
+ clone->_backupClone=const_cast<Part*>(this);
+ return clone;
+}
+
+Part* Part::duplicate() const
+{
+ Part* dup = duplicateEmpty();
+
+ // copy the eventlist; duplicate each Event(Ptr!).
+ for (MusECore::ciEvent i = _events.begin(); i != _events.end(); ++i)
+ dup->_events.add(i->second.clone());
+
+ return dup;
}
@@ -724,42 +507,21 @@ WavePart::WavePart(WaveTrack* t)
setType(FRAMES);
}
-WavePart::WavePart(WaveTrack* t, EventList* ev)
- : Part(t, ev)
- {
- setType(FRAMES);
- }
-
-//---------------------------------------------------------
-// WavePart
-// copy constructor
-//---------------------------------------------------------
-
-WavePart::WavePart(const WavePart& p) : Part(p)
-{
- _prevClone = this;
- _nextClone = this;
-}
-
//---------------------------------------------------------
// Part
//---------------------------------------------------------
Part::~Part()
- {
+{
if (_prevClone!=this || _nextClone!=this)
{
if (MusEGlobal::debugMsg) {
fprintf(stderr, "Part isn't unchained in ~Part()! Unchaining now...\n");
}
- unchainClone(this);
- }
-
- _events->incRef(-1);
- if (_events->refCount() <= 0)
- delete _events;
- }
+ unchainClone();
+ }
+}
//---------------------------------------------------------
@@ -852,55 +614,24 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo
switch(track->type()) {
case Track::WAVE:
{
- MusECore::WavePart* nPart = new MusECore::WavePart(*(MusECore::WavePart*)oPart);
- EventList* el = nPart->events();
- unsigned new_partlength = MusEGlobal::tempomap.deltaTick2frame(oPart->tick(), oPart->tick() + len);
-
- // If new nr of frames is less than previous what can happen is:
- // - 0 or more events are beginning after the new final position. Those are removed from the part
- // - The last event begins before new final position and ends after it. If so, it will be resized to end at new part length
- if (new_partlength < oPart->lenFrame()) {
- Undo operations;
-
- for (iEvent i = el->begin(); i != el->end(); i++) {
- Event e = i->second;
- unsigned event_startframe = e.frame();
- unsigned event_endframe = event_startframe + e.lenFrame();
- if (event_endframe < new_partlength)
- continue;
- }
- nPart->setLenFrame(new_partlength);
- // Do not do port controller values and clone parts.
- operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false));
-
- MusEGlobal::song->applyOperationGroup(operations);
- }
- // If the part is expanded there can be no additional events beginning after the previous final position
- // since those are removed if the part has been shrunk at some time (see above)
- // The only thing we need to check is the final event: If it has data after the previous final position,
- // we'll expand that event
- else {
- Undo operations;
- if(!el->empty())
- {
- iEvent i = el->end();
- i--;
- Event last = i->second;
- MusECore::SndFileR file = last.sndFile();
- if (file.isNull())
- return;
- Event newEvent = last.clone();
- // Do not do port controller values and clone parts.
- operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, last, nPart, false, false));
- }
-
- nPart->setLenFrame(new_partlength);
- // Do not do port controller values and clone parts.
- operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false));
- MusEGlobal::song->applyOperationGroup(operations);
- }
- }
+ Undo operations;
+
+ unsigned orig_len=oPart->lenFrame();
+ WavePart* part_it=(WavePart*)oPart;
+ do
+ {
+ if (part_it->lenFrame()==orig_len)
+ {
+ // Do port controller values but not clone parts.
+ operations.push_back(UndoOp(UndoOp::ModifyPartLengthFrames, part_it, part_it->lenFrame(), len, true, false));
+ }
+
+ part_it=(WavePart*)part_it->nextClone();
+ } while (doClones && (part_it != (WavePart*)oPart));
+
+ MusEGlobal::song->applyOperationGroup(operations);
break;
+ }
case Track::MIDI:
case Track::DRUM:
case Track::NEW_DRUM:
@@ -913,10 +644,8 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo
{
if (part_it->lenTick()==orig_len)
{
- MidiPart* newPart = new MidiPart(*part_it);
- newPart->setLenTick(len);
// Do port controller values but not clone parts.
- operations.push_back(UndoOp(UndoOp::ModifyPart, part_it, newPart, true, false));
+ operations.push_back(UndoOp(UndoOp::ModifyPartLength, part_it, part_it->lenTick(), len, true, false));
}
part_it=(MidiPart*)part_it->nextClone();
@@ -936,23 +665,23 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo
// create two new parts p1 and p2
//---------------------------------------------------------
-void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2)
+void Part::splitPart(int tickpos, Part*& p1, Part*& p2) const
{
int l1 = 0; // len of first new part (ticks or samples)
int l2 = 0; // len of second new part
int samplepos = MusEGlobal::tempomap.tick2frame(tickpos);
- switch (type()) {
- case WAVE:
- l1 = samplepos - part->frame();
- l2 = part->lenFrame() - l1;
+ switch (track()->type()) {
+ case Track::WAVE:
+ l1 = samplepos - frame();
+ l2 = lenFrame() - l1;
break;
- case MIDI:
- case DRUM:
- case NEW_DRUM:
- l1 = tickpos - part->tick();
- l2 = part->lenTick() - l1;
+ case Track::MIDI:
+ case Track::DRUM:
+ case Track::NEW_DRUM:
+ l1 = tickpos - tick();
+ l2 = lenTick() - l1;
break;
default:
return;
@@ -961,20 +690,18 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2)
if (l1 <= 0 || l2 <= 0)
return;
- p1 = newPart(part); // new left part
- p2 = newPart(part); // new right part
+ p1 = this->duplicateEmpty(); // new left part
+ p2 = this->duplicateEmpty(); // new right part
- // Added by Tim. p3.3.6
-
- switch (type()) {
- case WAVE:
+ switch (track()->type()) {
+ case Track::WAVE:
p1->setLenFrame(l1);
p2->setFrame(samplepos);
p2->setLenFrame(l2);
break;
- case MIDI:
- case DRUM:
- case NEW_DRUM:
+ case Track::MIDI:
+ case Track::DRUM:
+ case Track::NEW_DRUM:
p1->setLenTick(l1);
p2->setTick(tickpos);
p2->setLenTick(l2);
@@ -983,158 +710,41 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2)
break;
}
- p2->setSn(p2->newSn());
-
- EventList* se = part->events();
- EventList* de1 = p1->events();
- EventList* de2 = p2->events();
-
- if (type() == WAVE) {
- int ps = part->frame();
+ if (track()->type() == Track::WAVE) {
+ int ps = this->frame();
int d1p1 = p1->frame();
int d2p1 = p1->endFrame();
int d1p2 = p2->frame();
int d2p2 = p2->endFrame();
- for (iEvent ie = se->begin(); ie != se->end(); ++ie) {
- Event event = ie->second;
+ for (ciEvent ie = _events.begin(); ie != _events.end(); ++ie) {
+ const Event& event = ie->second;
int s1 = event.frame() + ps;
int s2 = event.endFrame() + ps;
if ((s2 > d1p1) && (s1 < d2p1)) {
Event si = event.mid(d1p1 - ps, d2p1 - ps);
- de1->add(si);
+ p1->_events.add(si);
}
if ((s2 > d1p2) && (s1 < d2p2)) {
Event si = event.mid(d1p2 - ps, d2p2 - ps);
- de2->add(si);
+ p2->_events.add(si);
}
}
}
else {
- for (iEvent ie = se->begin(); ie != se->end(); ++ie) {
+ for (ciEvent ie = _events.begin(); ie != _events.end(); ++ie) {
Event event = ie->second.clone();
int t = event.tick();
if (t >= l1) {
event.move(-l1);
- de2->add(event);
+ p2->_events.add(event);
}
else
- de1->add(event);
+ p1->_events.add(event);
}
}
}
-//---------------------------------------------------------
-// cmdSplitPart
-//---------------------------------------------------------
-
-void Song::cmdSplitPart(Track* track, Part* part, int tick)
- {
- int l1 = tick - part->tick();
- int l2 = part->lenTick() - l1;
- if (l1 <= 0 || l2 <= 0)
- return;
- Part* p1;
- Part* p2;
- track->splitPart(part, tick, p1, p2);
-
- //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ChangePart below
- MusEGlobal::song->informAboutNewParts(part, p2);
-
- startUndo();
- // Indicate no undo, and do port controller values but not clone parts.
- MusEGlobal::audio->msgChangePart(part, p1, false, true, false);
- MusEGlobal::audio->msgAddPart(p2, false);
- endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED);
- }
-
-//---------------------------------------------------------
-// changePart
-//---------------------------------------------------------
-
-void Song::changePart(Part* oPart, Part* nPart)
- {
- nPart->setSn(oPart->sn());
-
- Track* oTrack = oPart->track();
- Track* nTrack = nPart->track();
-
- oTrack->parts()->remove(oPart);
- nTrack->parts()->add(nPart);
-
-
- // Added by T356.
- // adjust song len:
- unsigned epos = nPart->tick() + nPart->lenTick();
- if (epos > len())
- _len = epos;
-
- }
-
-//---------------------------------------------------------
-// cmdGluePart
-//---------------------------------------------------------
-
-void Song::cmdGluePart(Track* track, Part* oPart)
- {
- // p3.3.54
- if(track->type() != Track::WAVE && !track->isMidiTrack())
- return;
-
- PartList* pl = track->parts();
- Part* nextPart = 0;
-
- for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
- if (ip->second == oPart) {
- ++ip;
- if (ip == pl->end())
- return;
- nextPart = ip->second;
- break;
- }
- }
-
- Part* nPart = track->newPart(oPart);
- nPart->setLenTick(nextPart->tick() + nextPart->lenTick() - oPart->tick());
-
- // populate nPart with Events from oPart and nextPart
-
- EventList* sl1 = oPart->events();
- EventList* dl = nPart->events();
-
- for (iEvent ie = sl1->begin(); ie != sl1->end(); ++ie)
- dl->add(ie->second);
-
- EventList* sl2 = nextPart->events();
-
- if(track->type() == Track::WAVE)
- {
- int frameOffset = nextPart->frame() - oPart->frame();
- for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie)
- {
- Event event = ie->second.clone();
- event.setFrame(event.frame() + frameOffset);
- dl->add(event);
- }
- }
- else
- if(track->isMidiTrack())
- {
- int tickOffset = nextPart->tick() - oPart->tick();
- for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie)
- {
- Event event = ie->second.clone();
- event.setTick(event.tick() + tickOffset);
- dl->add(event);
- }
- }
-
- startUndo();
- MusEGlobal::audio->msgRemovePart(nextPart, false);
- // Indicate no undo, and do port controller values but not clone parts.
- MusEGlobal::audio->msgChangePart(oPart, nPart, false, true, false);
- endUndo(SC_PART_MODIFIED | SC_PART_REMOVED);
- }
//---------------------------------------------------------
// dump
@@ -1169,21 +779,6 @@ void MidiPart::dump(int n) const
}
//---------------------------------------------------------
-// clone
-//---------------------------------------------------------
-
-MidiPart* MidiPart::clone() const
- {
- return new MidiPart(*this);
- }
-
-
-WavePart* WavePart::clone() const
- {
- return new WavePart(*this);
- }
-
-//---------------------------------------------------------
// hasHiddenEvents
// Returns combination of HiddenEventsType enum.
//---------------------------------------------------------
@@ -1193,7 +788,7 @@ int MidiPart::hasHiddenEvents()
unsigned len = lenTick();
// TODO: For now, we don't support events before the left border, only events past the right border.
- for(iEvent ev=events()->begin(); ev!=events()->end(); ev++)
+ for(ciEvent ev=_events.begin(); ev!=_events.end(); ev++)
{
if(ev->second.endTick() > len)
{
@@ -1215,7 +810,7 @@ int WavePart::hasHiddenEvents()
unsigned len = lenFrame();
// TODO: For now, we don't support events before the left border, only events past the right border.
- for(iEvent ev=events()->begin(); ev!=events()->end(); ev++)
+ for(ciEvent ev=_events.begin(); ev!=_events.end(); ev++)
{
if(ev->second.endFrame() > len)
{