summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Schweer <ws.seh.de>2006-11-26 10:09:03 +0000
committerWerner Schweer <ws.seh.de>2006-11-26 10:09:03 +0000
commit90c7251f4aaf954065f4841e4ec19b3fb53250a9 (patch)
tree65ab384c758b318c01cc803d3e85bee382a89191
parent53ec5d7c359e777fa1ed239ab73603d161070344 (diff)
updates
-rw-r--r--muse/muse/arranger/canvas.cpp23
-rw-r--r--muse/muse/audio.h2
-rw-r--r--muse/muse/event.cpp2
-rw-r--r--muse/muse/event.h44
-rw-r--r--muse/muse/eventbase.h2
-rw-r--r--muse/muse/eventlist.cpp12
-rw-r--r--muse/muse/midiedit/miditracker.cpp4
-rw-r--r--muse/muse/midiedit/trackpattern.cpp4
-rw-r--r--muse/muse/midieventbase.h2
-rw-r--r--muse/muse/miditrack.cpp12
-rw-r--r--muse/muse/miditrack.h5
-rw-r--r--muse/muse/part.cpp157
-rw-r--r--muse/muse/part.h24
-rw-r--r--muse/muse/song.h1
-rw-r--r--muse/muse/songpart.cpp53
-rw-r--r--muse/muse/sync.cpp12
-rw-r--r--muse/muse/undo.cpp57
-rw-r--r--muse/muse/waveevent.h2
-rw-r--r--muse/muse/wavetrack.cpp4
19 files changed, 203 insertions, 219 deletions
diff --git a/muse/muse/arranger/canvas.cpp b/muse/muse/arranger/canvas.cpp
index f050c492..358520f8 100644
--- a/muse/muse/arranger/canvas.cpp
+++ b/muse/muse/arranger/canvas.cpp
@@ -193,7 +193,7 @@ void PartCanvas::paint(QPainter& p, QRect r)
break;
QRect pr(x1, y, len, h - partBorderWidth);
- bool clone = part->isCloned();
+ bool clone = part->isClone();
QPen pen(Qt::black, partBorderWidth, clone ? Qt::DashLine : Qt::SolidLine);
QBrush brush(Qt::SolidPattern);
@@ -287,7 +287,7 @@ void PartCanvas::drawMidiPart(QPainter& p, Part* mp, int y, int th, int from, in
EventList* events = mp->events();
// iEvent ito(events->lower_bound(to));
- iEvent ito(events->end());
+ iEvent ito = events->end();
// int pos = pos2pix(*mp);
if (config.canvasShowPartType & 2) { // show events
@@ -440,7 +440,7 @@ void PartCanvas::contextMenu(const QPoint& pos)
a->setData(3);
a = pop->addAction(tr("de-clone"));
a->setData(15);
- a->setEnabled(part->events()->arefCount() > 1);
+ a->setEnabled(part->isClone());
if (track->type() == Track::MIDI) {
a = pop->addAction(tr("AutoFill..."));
a->setData(16);
@@ -875,20 +875,19 @@ void PartCanvas::setCursor()
// declonePart
//---------------------------------------------------------
-void PartCanvas::declonePart(Part* spart)
+void PartCanvas::declonePart(Part* oPart)
{
- Track* track = spart->track();
- Part* dpart = track->newPart(spart, false);
+ Track* track = oPart->track();
+ Part* nPart = track->newPart(oPart, false);
- EventList* se = spart->events();
- EventList* de = dpart->events();
+ EventList* se = oPart->events();
for (iEvent i = se->begin(); i != se->end(); ++i) {
Event oldEvent = i->second;
- Event ev = oldEvent.clone();
- de->add(ev);
+// Event ev = oldEvent.clone();
+ nPart->addEvent(oldEvent);
}
- song->cmdChangePart(spart, dpart);
- track->partListChanged();
+ oPart->deref();
+ song->cmdChangePart(oPart, nPart);
}
//---------------------------------------------------------
diff --git a/muse/muse/audio.h b/muse/muse/audio.h
index b136ca34..56ce1976 100644
--- a/muse/muse/audio.h
+++ b/muse/muse/audio.h
@@ -44,8 +44,6 @@ class Part;
class Event;
class MidiEvent;
class Event;
-class EventList;
-class MidiInstrument;
class MidiTrack;
class MidiSeq;
class MidiTrackBase;
diff --git a/muse/muse/event.cpp b/muse/muse/event.cpp
index 77438764..2985bb9c 100644
--- a/muse/muse/event.cpp
+++ b/muse/muse/event.cpp
@@ -70,7 +70,7 @@ void EventBase::dump(int n) const
// clone
//---------------------------------------------------------
-Event Event::clone()
+Event Event::clone() const
{
return Event(ev->clone());
}
diff --git a/muse/muse/event.h b/muse/muse/event.h
index c44ca622..cce5e84f 100644
--- a/muse/muse/event.h
+++ b/muse/muse/event.h
@@ -25,6 +25,7 @@
#include "al/xml.h"
#include "al/pos.h"
#include "evdata.h"
+#include "clonedata.h"
using AL::Xml;
using AL::Pos;
@@ -61,7 +62,7 @@ class Event {
void read(QDomNode);
void write(AL::Xml& xml, const Pos& offset) const;
void dump(int n = 0) const;
- Event clone();
+ Event clone() const;
Event mid(unsigned a, unsigned b);
bool isNote() const;
@@ -120,16 +121,10 @@ typedef std::pair <iEvent, iEvent> EventRange;
// tick sorted list of events
//---------------------------------------------------------
-class EventListData : public EL, public QSharedData {
- int aref; // number of active references (exclude undo list)
- void deselect();
-
+class EventList : public EL {
public:
- EventListData() { aref = 0; }
- ~EventListData() {}
-
- void incARef(int n) { aref += n; }
- int arefCount() const { return aref; }
+ int cloneCount;
+ EventList() { cloneCount = 0; }
iEvent find(const Event&);
iEvent add(Event& event);
iEvent add(Event& event, unsigned tick);
@@ -138,34 +133,5 @@ class EventListData : public EL, public QSharedData {
void read(QDomNode, bool midi);
};
-class EventList {
- QSharedDataPointer<EventListData> d;
-
- public:
- EventList() { d = new EventListData(); }
- void incARef(int n) { d->incARef(n); }
- int arefCount() const { return d->arefCount(); }
- iEvent find(const Event& event) { return d->find(event); }
- iEvent add(Event& event) { return d->add(event); }
- iEvent add(Event& event, unsigned tick) { return d->add(event, tick); }
- void move(Event& event, unsigned tick) { d->move(event, tick); }
- void dump() const { d->dump(); }
- void read(QDomNode n, bool midi) { d->read(n, midi); }
- iEvent begin() { return d->begin(); }
- iEvent end() { return d->end(); }
- ciEvent begin() const { return d->begin(); }
- ciEvent end() const { return d->end(); }
- iEvent lower_bound(unsigned n) { return d->lower_bound(n); }
- ciEvent lower_bound(unsigned n) const { return d->lower_bound(n); }
- iEvent upper_bound(unsigned n) { return d->upper_bound(n); }
- ciEvent upper_bound(unsigned n) const { return d->upper_bound(n); }
- EventRange equal_range(unsigned n) { return d->equal_range(n); }
- void clear() { d->clear(); }
- bool empty() const { return d->empty(); }
- void erase(iEvent i) { d->erase(i); }
- void erase(iEvent i, iEvent k) { d->erase(i, k); }
- unsigned size() const { return d->size(); }
- };
-
#endif
diff --git a/muse/muse/eventbase.h b/muse/muse/eventbase.h
index 80019a74..8381952e 100644
--- a/muse/muse/eventbase.h
+++ b/muse/muse/eventbase.h
@@ -86,7 +86,7 @@ class EventBase : public AL::PosLen {
virtual void setSpos(int) { }
virtual SndFileR sndFile() const { return 0; }
virtual void setSndFile(SndFileR&) { }
- virtual EventBase* clone() = 0;
+ virtual EventBase* clone() const = 0;
virtual void read(unsigned /*offset*/, float** /*bpp*/, int /*channels*/, int /*nn*/) {}
};
diff --git a/muse/muse/eventlist.cpp b/muse/muse/eventlist.cpp
index 9ce2930a..e8289fc3 100644
--- a/muse/muse/eventlist.cpp
+++ b/muse/muse/eventlist.cpp
@@ -25,7 +25,7 @@
// readEventList
//---------------------------------------------------------
-void EventListData::read(QDomNode node, bool midi)
+void EventList::read(QDomNode node, bool midi)
{
for (; !node.isNull(); node = node.nextSibling()) {
QDomElement e = node.toElement();
@@ -46,12 +46,12 @@ void EventListData::read(QDomNode node, bool midi)
// add
//---------------------------------------------------------
-iEvent EventListData::add(Event& event, unsigned tick)
+iEvent EventList::add(Event& event, unsigned tick)
{
return std::multimap<unsigned, Event, std::less<unsigned> >::insert(std::pair<const unsigned, Event> (tick, event));
}
-iEvent EventListData::add(Event& event)
+iEvent EventList::add(Event& event)
{
return add(event, event.tick());
}
@@ -60,7 +60,7 @@ iEvent EventListData::add(Event& event)
// move
//---------------------------------------------------------
-void EventListData::move(Event& event, unsigned tick)
+void EventList::move(Event& event, unsigned tick)
{
iEvent i = find(event);
erase(i);
@@ -71,7 +71,7 @@ void EventListData::move(Event& event, unsigned tick)
// find
//---------------------------------------------------------
-iEvent EventListData::find(const Event& event)
+iEvent EventList::find(const Event& event)
{
EventRange range = equal_range(event.tick());
for (iEvent i = range.first; i != range.second; ++i) {
@@ -85,7 +85,7 @@ iEvent EventListData::find(const Event& event)
// dump
//---------------------------------------------------------
-void EventListData::dump() const
+void EventList::dump() const
{
for (ciEvent i = begin(); i != end(); ++i)
i->second.dump();
diff --git a/muse/muse/midiedit/miditracker.cpp b/muse/muse/midiedit/miditracker.cpp
index 0b3e2652..af87d513 100644
--- a/muse/muse/midiedit/miditracker.cpp
+++ b/muse/muse/midiedit/miditracker.cpp
@@ -107,8 +107,8 @@ MidiTrackerEditor::MidiTrackerEditor(PartList* pl, bool /*init*/)
//-------------
//timing matrix
//-------------
- TimingPattern* timingPattern =
- new TimingPattern(this, "Timing", firstTick, lastTick, _quant);
+// TimingPattern* timingPattern =
+// new TimingPattern(this, "Timing", firstTick, lastTick, _quant);
//---------------
//tracks matrices
diff --git a/muse/muse/midiedit/trackpattern.cpp b/muse/muse/midiedit/trackpattern.cpp
index ee560e16..3a1fae64 100644
--- a/muse/muse/midiedit/trackpattern.cpp
+++ b/muse/muse/midiedit/trackpattern.cpp
@@ -237,7 +237,7 @@ bool VoicePat::isFreeSpace(const Event* e, unsigned tick) {
//----------------------------------------------------------
// CtrlPat
//----------------------------------------------------------
-CtrlPat::CtrlPat(QString name) {
+CtrlPat::CtrlPat(QString /*name*/) {
}
CtrlPat::~CtrlPat() {}
@@ -339,7 +339,7 @@ void TrackPattern::add(const Event* e, unsigned tick) {
}
}
-void TrackPattern::setQuant(int quant) {
+void TrackPattern::setQuant(int /*quant*/) {
//TODO
}
diff --git a/muse/muse/midieventbase.h b/muse/muse/midieventbase.h
index 5eee7fbe..bace6bec 100644
--- a/muse/muse/midieventbase.h
+++ b/muse/muse/midieventbase.h
@@ -31,7 +31,7 @@ class MidiEventBase : public EventBase {
int a, b, c; // pitch, velo-on, velo-off
EvData edata;
- virtual EventBase* clone() { return new MidiEventBase(*this); }
+ virtual EventBase* clone() const { return new MidiEventBase(*this); }
public:
MidiEventBase(EventType t);
diff --git a/muse/muse/miditrack.cpp b/muse/muse/miditrack.cpp
index 16373e71..f35642bf 100644
--- a/muse/muse/miditrack.cpp
+++ b/muse/muse/miditrack.cpp
@@ -40,7 +40,6 @@ MidiTrack::MidiTrack()
_delay = 0;
_len = 100; // percent
_compression = 100; // percent
- _events = new EventList;
initMidiController();
recordPart = 0;
@@ -62,23 +61,28 @@ MidiTrack::MidiTrack()
MidiTrack::~MidiTrack()
{
- delete _events;
}
//---------------------------------------------------------
// newPart
//---------------------------------------------------------
-Part* MidiTrack::newPart(Part*p, bool clone)
+Part* MidiTrack::newPart(Part* p, bool clone)
{
- Part* part = clone ? new Part(this, p->events()) : new Part(this);
+ Part* part = new Part(this);
if (p) {
+ if (clone)
+ part->clone(p->events());
+ else
+ part->ref();
part->setName(p->name());
part->setColorIndex(p->colorIndex());
*(AL::PosLen*)part = *(AL::PosLen*)p;
part->setMute(p->mute());
}
+ else
+ part->ref();
return part;
}
diff --git a/muse/muse/miditrack.h b/muse/muse/miditrack.h
index 6424c1d8..6aad602f 100644
--- a/muse/muse/miditrack.h
+++ b/muse/muse/miditrack.h
@@ -23,6 +23,7 @@
#include "miditrackbase.h"
#include "midififo.h"
+#include "event.h"
class Part;
class EventList;
@@ -35,7 +36,7 @@ class MidiOut;
class MidiTrack : public MidiTrackBase {
Q_OBJECT
- EventList* _events; // tmp Events during midi import
+ EventList _events; // tmp Events during midi import
// recording:
MidiFifo recordFifo; // for event transfer from RT-thread to gui thread
@@ -90,7 +91,7 @@ class MidiTrack : public MidiTrackBase {
void recordBeat();
void stopRecording();
- EventList* events() const { return _events; }
+ EventList* events() { return &_events; }
virtual void read(QDomNode);
virtual void write(Xml&) const;
diff --git a/muse/muse/part.cpp b/muse/muse/part.cpp
index fa199036..6889f061 100644
--- a/muse/muse/part.cpp
+++ b/muse/muse/part.cpp
@@ -49,83 +49,32 @@ const char* partColorNames[] = {
CloneList cloneList;
//---------------------------------------------------------
-// init
+// Part
//---------------------------------------------------------
-void Part::init()
+Part::Part(Track* t)
{
- _raster = -1; // invalid
- _quant = -1;
- _xmag = -1.0;
-
_selected = false;
_mute = false;
_colorIndex = 0;
+ _raster = -1; // invalid
+ _quant = -1;
+ _xmag = -1.0;
_fillLen = 0;
- _events->incARef(1);
+ _track = t;
+ _events = 0;
if (_track->type() == Track::WAVE)
setType(AL::FRAMES);
}
//---------------------------------------------------------
-// Part
-//---------------------------------------------------------
-
-Part::Part(Track* t)
- {
- _track = t;
- _events = new EventList;
- init();
- }
-
-Part::Part(const Part& p)
- : PosLen(p)
- {
- _track = p._track;
- _selected = p._selected;
- _mute = p._mute;
- _colorIndex = p._colorIndex;
- _name = p._name;
- _events = p._events;
- _quant = p._quant;
- _raster = p._raster;
- _xmag = p._xmag;
- _fillLen = p._fillLen;
- }
-
-Part::Part(const Part& p, EventList* el)
- : PosLen(p)
- {
- _track = p._track;
- _selected = p._selected;
- _mute = p._mute;
- _colorIndex = p._colorIndex;
- _name = p._name;
- _quant = p._quant;
- _raster = p._raster;
- _xmag = p._xmag;
- _fillLen = p._fillLen;
- _events = el;
- _events->incARef(1);
- }
-
-//---------------------------------------------------------
-// Part
-//---------------------------------------------------------
-
-Part::Part(Track* t, EventList* el)
- {
- _track = t;
- _events = el;
- init();
- }
-
-//---------------------------------------------------------
-// Part
+// clone
//---------------------------------------------------------
-Part::~Part()
+void Part::clone(EventList* e)
{
+ _events = e;
+ ref();
}
//---------------------------------------------------------
@@ -137,6 +86,11 @@ iEvent Part::addEvent(Event& p)
return _events->add(p);
}
+iEvent Part::addEvent(Event& p, unsigned t)
+ {
+ return _events->add(p, t);
+ }
+
//---------------------------------------------------------
// index
//---------------------------------------------------------
@@ -234,28 +188,25 @@ void Part::dump(int n) const
// Part::write
//---------------------------------------------------------
-void Part::write(Xml& xml) const
+void Part::write(Xml& xml)
{
- const EventList* el = events();
int id = -1;
bool dumpEvents = true;
- if (isCloned()) {
+
+ if (isClone()) {
// we have to dump the event list only on first
// incarnation of clone
for (iClone i = cloneList.begin(); i != cloneList.end(); ++i) {
- if (i->el == el) {
+ if (i->el == _events) {
id = i->id;
dumpEvents = false;
break;
}
}
- if (id == -1) {
- id = cloneList.size();
- ClonePart cp(el, id);
- cloneList.push_back(cp);
- }
+ if (id == -1)
+ cloneList.push_back(ClonePart(_events, cloneList.size()));
}
if (id != -1)
@@ -283,7 +234,7 @@ void Part::write(Xml& xml) const
if (_mute)
xml.intTag("mute", _mute);
if (dumpEvents) {
- for (ciEvent e = el->begin(); e != el->end(); ++e)
+ for (ciEvent e = _events->begin(); e != _events->end(); ++e)
e->second.write(xml, *this);
}
xml.etag("part");
@@ -297,7 +248,6 @@ void Part::read(QDomNode node)
{
QDomElement e = node.toElement();
int id = e.attribute("cloneId", "-1").toInt();
- bool containsEvents = false;
ctrlCanvasList.clear();
for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) {
@@ -330,7 +280,6 @@ void Part::read(QDomNode node)
else if (tag == "fillLen")
_fillLen = i;
else if (tag == "event") {
- containsEvents = true;
EventType type = Wave;
if (_track->isMidiTrack())
type = Note;
@@ -354,7 +303,7 @@ void Part::read(QDomNode node)
mc->addControllerVal(e.dataA(), tick, v);
}
else
- _events->add(e);
+ _events.add(e);
}
else
#endif
@@ -366,34 +315,54 @@ void Part::read(QDomNode node)
}
if (id != -1) {
- // clone part
- if (containsEvents) {
+ bool found = false;
+ for (iClone i = cloneList.begin(); i != cloneList.end(); ++i) {
+ if (i->id == id) {
+ if (_events->size())
+ printf("MusE::internal error: clone part contains events\n");
+ clone(i->el);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
// add to cloneList:
ClonePart cp(_events, id);
cloneList.push_back(cp);
}
- else {
- // replace event list with clone event
- // list
- for (iClone i = cloneList.begin();
- i != cloneList.end(); ++i) {
- if (i->id == id) {
- delete _events;
- _events = (EventList*)(i->el);
- _events->incARef(1);
- break;
- }
- }
- }
}
}
//---------------------------------------------------------
-// isCloned
-// return true if this part is cloned
+// isClone
+//---------------------------------------------------------
+
+bool Part::isClone() const
+ {
+ return _events->cloneCount > 1;
+ }
+
+//---------------------------------------------------------
+// ref
//---------------------------------------------------------
-bool Part::isCloned() const
+void Part::ref()
{
- return _events->arefCount() > 1;
+ if (_events == 0)
+ _events = new EventList;
+ ++(_events->cloneCount);
}
+
+//---------------------------------------------------------
+// deref
+//---------------------------------------------------------
+
+void Part::deref()
+ {
+ --(_events->cloneCount);
+ if (_events->cloneCount <= 0) {
+ delete _events;
+ _events = 0;
+ }
+ }
+
diff --git a/muse/muse/part.h b/muse/muse/part.h
index 5f898f1a..8a7c80f0 100644
--- a/muse/muse/part.h
+++ b/muse/muse/part.h
@@ -33,10 +33,14 @@ namespace AL {
using AL::Xml;
+//---------------------------------------------------------
+// ClonePart
+//---------------------------------------------------------
+
struct ClonePart {
- const EventList* el;
+ EventList* el;
int id;
- ClonePart(const EventList* e, int i) : el(e), id(i) {}
+ ClonePart(EventList* e, int i) : el(e), id(i) {}
};
typedef std::list<ClonePart> CloneList;
@@ -74,18 +78,12 @@ class Part : public AL::PosLen {
// auto fill:
int _fillLen; // = 0 if no auto fill
- void init();
-
protected:
Track* _track;
EventList* _events;
public:
Part(Track*);
- Part(Track*, EventList*);
- Part(const Part&, EventList*);
- Part(const Part&);
- ~Part();
CtrlCanvasList* getCtrlCanvasList() { return &ctrlCanvasList; }
@@ -114,17 +112,21 @@ class Part : public AL::PosLen {
void setXmag(double val) { _xmag = val; }
EventList* events() const { return _events; }
- void setEventList(EventList* e) { _events = e; }
+
+ void clone(EventList* e);
iEvent addEvent(Event& p);
+ iEvent addEvent(Event& p, unsigned);
int fillLen() const { return _fillLen; }
void setFillLen(int val) { _fillLen = val; }
void read(QDomNode);
- void write(Xml&) const;
+ void write(Xml&);
void dump(int n = 0) const;
- bool isCloned() const;
+ bool isClone() const;
+ void deref();
+ void ref();
};
//---------------------------------------------------------
diff --git a/muse/muse/song.h b/muse/muse/song.h
index 6c31c879..895ff3ee 100644
--- a/muse/muse/song.h
+++ b/muse/muse/song.h
@@ -131,6 +131,7 @@ class Song : public QObject {
int _globalPitchShift;
void readMarker(QDomNode);
void restartJack();
+ void undoPartModify(Part* oPart, Part* nPart, bool undo);
public slots:
void beat();
diff --git a/muse/muse/songpart.cpp b/muse/muse/songpart.cpp
index d8177a69..e561476b 100644
--- a/muse/muse/songpart.cpp
+++ b/muse/muse/songpart.cpp
@@ -80,22 +80,6 @@ void Song::cmdRemovePart(Part* part)
startUndo();
removePart(part);
endUndo(0);
- part->track()->partListChanged();
- }
-
-//---------------------------------------------------------
-// removePart
-//---------------------------------------------------------
-
-void Song::removePart(Part* part)
- {
- AudioMsg msg;
- msg.id = SEQM_REMOVE_PART;
- msg.p1 = part;
- audio->sendMessage(&msg, false);
- undoOp(UndoOp::DeletePart, part);
- part->events()->incARef(-1);
- updateFlags |= SC_PART_REMOVED;
}
//---------------------------------------------------------
@@ -115,8 +99,26 @@ void Song::cmdRemoveParts()
pl.add(ip->second);
}
}
+ startUndo();
for (iPart ip = pl.begin(); ip != pl.end(); ++ip)
removePart(ip->second);
+ endUndo(0);
+ }
+
+//---------------------------------------------------------
+// removePart
+//---------------------------------------------------------
+
+void Song::removePart(Part* part)
+ {
+ AudioMsg msg;
+ msg.id = SEQM_REMOVE_PART;
+ msg.p1 = part;
+ audio->sendMessage(&msg, false);
+ undoOp(UndoOp::DeletePart, part);
+ updateFlags |= SC_PART_REMOVED;
+ part->deref();
+ part->track()->partListChanged();
}
//---------------------------------------------------------
@@ -129,6 +131,7 @@ void Song::cmdChangePart(Part* oldPart, Part* newPart)
startUndo();
changePart(oldPart, newPart);
endUndo(0);
+ newPart->track()->partListChanged();
}
//---------------------------------------------------------
@@ -143,7 +146,6 @@ void Song::changePart(Part* oldPart, Part* newPart)
msg.p2 = newPart;
audio->sendMessage(&msg, false);
undoOp(UndoOp::ModifyPart, oldPart, newPart);
- oldPart->events()->incARef(-1);
updateFlags = SC_PART_MODIFIED;
if (len() < newPart->endTick())
setLen(newPart->endTick());
@@ -161,33 +163,32 @@ void Song::cmdChangePart(Part* oPart, unsigned pos, unsigned len)
// move events so they stay at same position in song
//
int delta = oPart->tick() - pos;
- EventList* d = new EventList();
- EventList* s = oPart->events();
- for (iEvent ie = s->begin(); ie != s->end(); ++ie) {
+ Part* nPart = new Part(*oPart);
+ const EventList* s = oPart->events();
+ for (ciEvent ie = s->begin(); ie != s->end(); ++ie) {
int tick = ie->first + delta;
if (tick >= 0 && tick < int(len)) {
Event ev = ie->second.clone();
ev.move(delta);
- d->add(ev, unsigned(tick));
+ nPart->addEvent(ev, unsigned(tick));
}
}
if (oPart->fillLen() > 0 && len < (unsigned)oPart->fillLen())
oPart->setFillLen(len);
if (oPart->lenTick() < len && oPart->fillLen() > 0) {
- unsigned loop = oPart->fillLen();
+ unsigned loop = oPart->fillLen();
unsigned fillLen = len - oPart->lenTick();
for (unsigned i = 0; i < fillLen / loop; ++i) {
int start = oPart->lenTick() + loop * i;
- for (iEvent ie = s->begin(); ie != s->end(); ++ie) {
+ for (ciEvent ie = s->begin(); ie != s->end(); ++ie) {
if (ie->first >= loop)
break;
Event ev = ie->second.clone();
ev.move(start);
- d->add(ev, ie->first + start);
+ nPart->addEvent(ev, ie->first + start);
}
}
}
- Part* nPart = new Part(*oPart, d);
nPart->setLenTick(len);
nPart->setTick(pos);
changePart(oPart, nPart);
@@ -236,7 +237,7 @@ void Song::cmdLinkPart(Part* sPart, unsigned pos, Track* track)
void Song::cmdCopyPart(Part* sPart, unsigned pos, Track* track)
{
- bool clone = sPart->events()->arefCount() > 1;
+ bool clone = sPart->isClone();
Part* dPart = track->newPart(sPart, clone);
dPart->setTick(pos);
if (!clone) {
diff --git a/muse/muse/sync.cpp b/muse/muse/sync.cpp
index ecef91fe..d089ce80 100644
--- a/muse/muse/sync.cpp
+++ b/muse/muse/sync.cpp
@@ -43,13 +43,13 @@ bool acceptMC = true;
bool acceptMMC = true;
static MTC mtcCurTime;
-static int mtcState; // 0-7 next expected quarter message
-static bool mtcValid;
-static int mtcLost;
-static bool mtcSync; // receive complete mtc frame?
+// static int mtcState; // 0-7 next expected quarter message
+// static bool mtcValid;
+// static int mtcLost;
+// static bool mtcSync; // receive complete mtc frame?
-static bool mcStart = false;
-static int mcStartTick;
+//static bool mcStart = false;
+//static int mcStartTick;
enum {
MMC_STOP = 1,
diff --git a/muse/muse/undo.cpp b/muse/muse/undo.cpp
index 66315a78..403227ac 100644
--- a/muse/muse/undo.cpp
+++ b/muse/muse/undo.cpp
@@ -151,13 +151,13 @@ void Song::doUndo2()
Part* part = i->oPart;
part->track()->parts()->remove(part);
updateFlags |= SC_PART_REMOVED;
- i->oPart->events()->incARef(-1);
+ part->deref();
}
break;
case UndoOp::DeletePart:
i->oPart->track()->addPart(i->oPart);
updateFlags |= SC_PART_INSERTED;
- i->oPart->events()->incARef(1);
+ i->oPart->ref();
break;
case UndoOp::ModifyPart:
{
@@ -166,6 +166,8 @@ void Song::doUndo2()
Part part = *newPart;
*newPart = *oldPart;
*oldPart = part;
+// oldPart->deref();
+// newPart->ref();
updateFlags |= SC_PART_MODIFIED;
}
break;
@@ -245,14 +247,14 @@ void Song::doRedo2()
case UndoOp::AddPart:
i->oPart->track()->addPart(i->oPart);
updateFlags |= SC_PART_INSERTED;
- i->oPart->events()->incARef(1);
+ i->oPart->ref();
break;
case UndoOp::DeletePart:
{
Part* part = i->oPart;
part->track()->parts()->remove(part);
updateFlags |= SC_PART_REMOVED;
- i->oPart->events()->incARef(-1);
+ part->deref();
}
break;
case UndoOp::ModifyPart:
@@ -263,6 +265,8 @@ void Song::doRedo2()
*newPart = *oldPart;
*oldPart = part;
updateFlags |= SC_PART_MODIFIED;
+// oldPart->ref();
+// newPart->deref();
}
break;
case UndoOp::AddEvent:
@@ -410,6 +414,7 @@ void Song::addUndo(UndoOp& i)
{
if (!undoMode) {
printf("internal error: undoOp without startUndo()\n");
+abort();
return;
}
undoList->back().push_back(i);
@@ -470,8 +475,8 @@ void Song::doUndo3()
}
break;
case UndoOp::ModifyPart:
- if (i->oPart->track() != i->nPart->track())
- i->nPart->track()->partListChanged();
+ undoPartModify(i->oPart, i->nPart, true);
+
case UndoOp::AddPart:
case UndoOp::DeletePart:
i->oPart->track()->partListChanged();
@@ -542,8 +547,8 @@ void Song::doRedo3()
removeTrack3(i->track);
break;
case UndoOp::ModifyPart:
- if (i->oPart->track() != i->nPart->track())
- i->nPart->track()->partListChanged();
+ undoPartModify(i->oPart, i->nPart, false);
+
case UndoOp::AddPart:
case UndoOp::DeletePart:
i->oPart->track()->partListChanged();
@@ -562,3 +567,39 @@ void Song::doRedo3()
dirty = true;
}
+//---------------------------------------------------------
+// undoPartModify
+//---------------------------------------------------------
+
+void Song::undoPartModify(Part* oPart, Part* nPart, bool undo)
+ {
+ if (oPart->track() != nPart->track())
+ nPart->track()->partListChanged();
+ //
+ // look for cloned part
+ //
+ for (iMidiTrack i = _midis.begin(); i != _midis.end(); ++i) {
+ PartList* pl = (*i)->parts();
+ for (iPart ip = pl->begin(); ip != pl->end(); ++ip) {
+ Part* p = ip->second;
+ if (undo) {
+ if (p == nPart)
+ continue;
+ if (p->events() == nPart->events()) {
+ // this is a cloned Part
+ p->ref();
+ return;
+ }
+ }
+ else {
+ if (p == oPart)
+ continue;
+ if (p->events() == oPart->events()) {
+ p->deref();
+ return;
+ }
+ }
+ }
+ }
+ }
+
diff --git a/muse/muse/waveevent.h b/muse/muse/waveevent.h
index e0c681fd..079c4425 100644
--- a/muse/muse/waveevent.h
+++ b/muse/muse/waveevent.h
@@ -33,7 +33,7 @@ class WaveEventBase : public EventBase {
int _spos; // start sample position in WaveFile
bool deleted;
- virtual EventBase* clone() { return new WaveEventBase(*this); }
+ virtual EventBase* clone() const { return new WaveEventBase(*this); }
public:
WaveEventBase(EventType t);
diff --git a/muse/muse/wavetrack.cpp b/muse/muse/wavetrack.cpp
index c022c3c1..14f2ef4a 100644
--- a/muse/muse/wavetrack.cpp
+++ b/muse/muse/wavetrack.cpp
@@ -170,8 +170,10 @@ void WaveTrack::read(QDomNode node)
Part* WaveTrack::newPart(Part*p, bool clone)
{
- Part* part = clone ? new Part(this, p->events()) : new Part(this);
+ Part* part = new Part(this);
if (p) {
+ if (clone)
+ part->clone(p->events());
part->setName(p->name());
part->setColorIndex(p->colorIndex());