diff options
42 files changed, 371 insertions, 743 deletions
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 5cad107a..860a33ac 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -383,28 +383,17 @@ bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& else { MusECore::Part* dpart; - bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->events()->arefCount() > 1)); + bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->hasClones())); // This increments aref count if cloned, and chains clones. // It also gives the new part a new serial number. - dpart = dtrack->newPart(spart, clone); + if (clone) + dpart = spart->createNewClone(); + else + dpart = spart->duplicate(); dpart->setTick(dtick); - if (t == MOVE_COPY && !clone) { - // Copy Events - MusECore::EventList* se = spart->events(); - MusECore::EventList* de = dpart->events(); - for (MusECore::iEvent i = se->begin(); i != se->end(); ++i) { - MusECore::Event oldEvent = i->second; - MusECore::Event ev = oldEvent.clone(); - de->add(ev); - } - } - dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - // so we must decrement it first :/ - // These will not increment ref count, and will not chain clones... - // TODO DELETETHIS: is the above comment still correct (by flo93)? i doubt it! operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart)); new_partend=(dpart->lenTick() + dpart->tick()); @@ -713,7 +702,7 @@ QMenu* PartCanvas::genItemPopup(CItem* item) act_copy->setShortcut(Qt::CTRL+Qt::Key_C); partPopup->addSeparator(); - int rc = npart->part()->events()->arefCount(); + int rc = npart->part()->nClones(); QString st = QString(tr("s&elect ")); if(rc > 1) st += (QString().setNum(rc) + QString(" ")); @@ -847,16 +836,8 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) case 15: // declone { MusECore::Part* spart = npart->part(); - MusECore::Track* track = npart->track(); - MusECore::Part* dpart = track->newPart(spart, false); - - MusECore::EventList* se = spart->events(); - MusECore::EventList* de = dpart->events(); - for (MusECore::iEvent i = se->begin(); i != se->end(); ++i) { - MusECore::Event oldEvent = i->second; - MusECore::Event ev = oldEvent.clone(); - de->add(ev); - } + MusECore::Part* dpart = spart->duplicate(); // dpart will not be member of any clone chain! + Undo operations; operations.push_back(UndoOp(UndoOp::DeletePart, spart)); operations.push_back(UndoOp(UndoOp::AddPart, dpart)); @@ -884,9 +865,8 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) case 17: // File info { MusECore::Part* p = item->part(); - MusECore::EventList* el = p->events(); QString str = tr("Part name: %1\nFiles:").arg(p->name()); - for (MusECore::iEvent e = el->begin(); e != el->end(); ++e) + for (MusECore::ciEvent e = p->events().begin(); e != p->events().end(); ++e) { MusECore::Event event = e->second; MusECore::SndFileR f = event.sndFile(); @@ -905,16 +885,13 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) // Traverse and process the clone chain ring until we arrive at the same part again. // The loop is a safety net. MusECore::Part* p = part; - int j = part->cevents()->arefCount(); - if(j > 0) + + if(part->hasClones()) { - for(int i = 0; i < j; ++i) - { - p->setSelected(true); - p = p->nextClone(); - if(p == part) - break; - } + p->setSelected(true); + for(MusECore::Part* it = p->nextClone(); it!=p; it=it->nextClone()) + it->setSelected(true); + MusEGlobal::song->update(SC_SELECTION); } @@ -1498,7 +1475,6 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect) if((unsigned int)to > part->lenTick()) to = part->lenTick(); - bool clone = part->events()->arefCount() > 1; QBrush brush; QRect r = item->bbox(); @@ -1723,12 +1699,11 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect) drawWavePart(p, rect, wp, r); else if (mp) { - drawMidiPart(p, rect, mp->events(), (MusECore::MidiTrack*)part->track(), mp, r, mp->tick(), from, to); + drawMidi*** /* FIXME: just give it the mp, not mp->whatever*/Part(p, rect, mp->events(), (MusECore::MidiTrack*)part->track(), mp, r, mp->tick(), from, to); } p.setWorldMatrixEnabled(false); - #if 1 // DELETETHIS remove wrapping #if // // Now draw the borders, using custom segments... // @@ -1756,7 +1731,7 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect) penNormal2V.setCosmetic(true); QVector<qreal> customDashPattern; - if(clone) + if(part->hasClones()) { customDashPattern << 4.0 << 6.0; penSelect1H.setDashPattern(customDashPattern); @@ -1819,8 +1794,6 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect) QLine l3(lbx_c, ye_0, rbx_c, ye_0); p.drawLine(l3); // Bottom line - #endif - if (MusEGlobal::config.canvasShowPartType & 1) { // show names // draw name // FN: Set text color depending on part color (black / white) @@ -2140,8 +2113,7 @@ void PartCanvas::drawWavePart(QPainter& p, int h = hh/2; int y = pr.y() + h; - MusECore::EventList* el = wp->events(); - for (MusECore::iEvent e = el->begin(); e != el->end(); ++e) { + for (MusECore::ciEvent e = wp->events().begin(); e != wp->events().end(); ++e) { int cc = hh % 2 ? 0 : 1; MusECore::Event event = e->second; MusECore::SndFileR f = event.sndFile(); @@ -2350,8 +2322,6 @@ void PartCanvas::copy_in_range(MusECore::PartList* pl_) MusECore::Part* p2; track->splitPart(part, lpos, p1, p2); - p1->events()->incARef(-1); - p2->events()->incARef(-1); part=p2; } @@ -2362,8 +2332,6 @@ void PartCanvas::copy_in_range(MusECore::PartList* pl_) MusECore::Part* p2; track->splitPart(part, rpos, p1, p2); - p1->events()->incARef(-1); - p2->events()->incARef(-1); part=p1; } @@ -2459,7 +2427,7 @@ MusECore::Undo PartCanvas::pasteAt(const QString& pt, MusECore::Track* track, un if (tag == "part") { // Read the part. MusECore::Part* p = 0; - p = readXmlPart(xml, track, clone, toTrack); + p = Part::readFromXml(xml, track, clone, toTrack); // If it could not be created... if(!p) @@ -2469,9 +2437,6 @@ MusECore::Undo PartCanvas::pasteAt(const QString& pt, MusECore::Track* track, un break; } - p->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - // so we must decrement it first :/ - // Increment the number of parts done. ++done; @@ -3045,10 +3010,9 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect) MusECore::MidiTrack *mt = (MusECore::MidiTrack*)track; QRect partRect(startPos,yPos, MusEGlobal::song->cpos()-startPos, track->height()); // probably the wrong rect MusECore::EventList myEventList; - MusECore::MPEventList *el = mt->mpevents(); - if (el->size()) { + if (mt->mpevents.size()) { - for (MusECore::ciMPEvent i = el->begin(); i != el->end(); ++i) { + for (MusECore::ciMPEvent i = mt->mpevents.begin(); i != mt->mpevents.end(); ++i) { MusECore::MidiPlayEvent pe = *i; if (pe.isNote() && !pe.isNoteOff()) { diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 8535a9f5..b27a48e1 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -723,7 +723,7 @@ void TList::ctrlValueFinished() { if (p->second->tick()==0) { - for (MusECore::iEvent ev=p->second->events()->begin(); ev!=p->second->events()->end(); ev++) + for (MusECore::ciEvent ev=p->second->events().begin(); ev!=p->second->events().end(); ev++) { if (ev->second.tick()!=0) break; else if (ev->second.type()==MusECore::Controller && ev->second.dataA()==ctrl_num) @@ -2150,7 +2150,7 @@ void TList::mousePressEvent(QMouseEvent* ev) { if (p->second->tick()==0) { - for (MusECore::iEvent ev=p->second->events()->begin(); ev!=p->second->events()->end(); ev++) + for (MusECore::ciEvent ev=p->second->events().begin(); ev!=p->second->events().end(); ev++) { if (ev->second.tick()!=0) break; else if (ev->second.type()==MusECore::Controller && ev->second.dataA()==ctrl_num) @@ -2550,8 +2550,7 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y) MusECore::PartList* pl = t->parts(); MusECore::MidiTrack* m = (MusECore::MidiTrack*) t; for (MusECore::iPart ip = pl->begin(); ip != pl->end(); ++ip) { - MusECore::EventList* el = ip->second->events(); - for (MusECore::iEvent ie = el->begin(); ie != el->end(); ++ie) { + for (MusECore::ciEvent ie = ip->second->events().begin(); ie != ip->second->events().end(); ++ie) { MusECore::Event ev = ie->second; if(ev.type() == MusECore::Note) { @@ -2590,8 +2589,7 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y) MusECore::PartList* pl = t->parts(); MusECore::MidiTrack* m = (MusECore::MidiTrack*) t; for (MusECore::iPart ip = pl->begin(); ip != pl->end(); ++ip) { - MusECore::EventList* el = ip->second->events(); - for (MusECore::iEvent ie = el->begin(); ie != el->end(); ++ie) { + for (MusECore::ciEvent ie = ip->second->events().begin(); ie != ip->second->events().end(); ++ie) { MusECore::Event ev = ie->second; if (ev.type() == MusECore::Note) { diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp index bbc803c5..914ff506 100644 --- a/muse2/muse/audio.cpp +++ b/muse2/muse/audio.cpp @@ -1027,19 +1027,17 @@ void Audio::recordStop() MidiTrackList* ml = MusEGlobal::song->midis(); for (iMidiTrack it = ml->begin(); it != ml->end(); ++it) { MidiTrack* mt = *it; - MPEventList* mpel = mt->mpevents(); - EventList* el = mt->events(); //--------------------------------------------------- // resolve NoteOff events, Controller etc. //--------------------------------------------------- // Do SysexMeta. Do loops. - buildMidiEventList(el, mpel, mt, MusEGlobal::config.division, true, true); - MusEGlobal::song->cmdAddRecordedEvents(mt, el, + buildMidiEventList(&mt->events, mt->mpevents, mt, MusEGlobal::config.division, true, true); + MusEGlobal::song->cmdAddRecordedEvents(mt, mt->events, MusEGlobal::extSyncFlag.value() ? startExternalRecTick : startRecordPos.tick()); - el->clear(); - mpel->clear(); + mt->events.clear(); + mt->mpevents.clear(); } // diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index d5adbc4f..8dd7fa9a 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -608,14 +608,13 @@ void CtrlCanvas::updateItems() if (filterTrack && part->track() != curTrack) continue; - MusECore::EventList* el = part->events(); MusECore::MidiCtrlValList* mcvl; partControllers(part, _cnum, 0, 0, 0, &mcvl); unsigned len = part->lenTick(); - for (MusECore::iEvent i = el->begin(); i != el->end(); ++i) + for (MusECore::ciEvent i = part->events().begin(); i != part->events().end(); ++i) { - MusECore::Event e = i->second; + const MusECore::Event& e = i->second; // Do not add events which are past the end of the part. if(e.tick() >= len) break; diff --git a/muse2/muse/event.cpp b/muse2/muse/event.cpp index 1a2d3c6e..73611448 100644 --- a/muse2/muse/event.cpp +++ b/muse2/muse/event.cpp @@ -74,7 +74,7 @@ void EventBase::dump(int n) const // clone //--------------------------------------------------------- -Event Event::clone() +Event Event::clone() const { #ifdef USE_SAMPLERATE return Event(ev->clone(), _audConv); diff --git a/muse2/muse/event.h b/muse2/muse/event.h index 8da37d4f..78ac7f93 100644 --- a/muse2/muse/event.h +++ b/muse2/muse/event.h @@ -73,7 +73,7 @@ class Event { void read(Xml& xml); void write(int a, Xml& xml, const Pos& offset, bool ForceWavePaths = false) const; void dump(int n = 0) const; - Event clone(); + Event clone() const; Event mid(unsigned a, unsigned b); bool isNote() const; @@ -124,7 +124,7 @@ typedef std::multimap <unsigned, Event, std::less<unsigned> > EL; typedef EL::iterator iEvent; typedef EL::reverse_iterator riEvent; typedef EL::const_iterator ciEvent; -typedef std::pair <iEvent, iEvent> EventRange; +typedef std::pair <ciEvent, ciEvent> EventRange; //--------------------------------------------------------- // EventList @@ -132,19 +132,9 @@ typedef std::pair <iEvent, iEvent> EventRange; //--------------------------------------------------------- class EventList : public EL { - int ref; // number of references to this EventList - int aref; // number of active references (exclude undo list) void deselect(); public: - EventList() { ref = 0; aref = 0; } - ~EventList() {} - - void incRef(int n) { ref += n; } - int refCount() const { return ref; } - void incARef(int n) { aref += n; } - int arefCount() const { return aref; } - iEvent find(const Event&); iEvent add(Event& event); void move(Event& event, unsigned tick); diff --git a/muse2/muse/eventbase.h b/muse2/muse/eventbase.h index 0cb960d9..9e7b2df8 100644 --- a/muse2/muse/eventbase.h +++ b/muse2/muse/eventbase.h @@ -95,7 +95,7 @@ class EventBase : public 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 readAudio(WavePart* /*part*/, unsigned /*offset*/, float** /*bpp*/, int /*channels*/, int /*nn*/, bool /*doSeek*/, bool /*overwrite*/) { } diff --git a/muse2/muse/exportmidi.cpp b/muse2/muse/exportmidi.cpp index e5cd74e1..aa9b83cc 100644 --- a/muse2/muse/exportmidi.cpp +++ b/muse2/muse/exportmidi.cpp @@ -131,11 +131,11 @@ static void addController(MPEventList* l, int tick, int port, int channel, int a // track can be NULL meaning no concept of drum notes is allowed in init sequences. //--------------------------------------------------------- -static void addEventList(MusECore::EventList* evlist, MusECore::MPEventList* mpevlist, MusECore::MidiTrack* track, MusECore::Part* part, int port, int channel) +static void addEventList(const MusECore::EventList& evlist, MusECore::MPEventList* mpevlist, MusECore::MidiTrack* track, MusECore::Part* part, int port, int channel) { - for (MusECore::iEvent i = evlist->begin(); i != evlist->end(); ++i) + for (MusECore::ciEvent i = evlist.begin(); i != evlist.end(); ++i) { - MusECore::Event ev = i->second; + const MusECore::Event& ev = i->second; int tick = ev.tick(); if(part) tick += part->tick(); @@ -519,8 +519,7 @@ void MusE::exportMidi() MusECore::PartList* parts = track->parts(); for (MusECore::iPart p = parts->begin(); p != parts->end(); ++p) { MusECore::MidiPart* part = (MusECore::MidiPart*) (p->second); - MusECore::EventList* evlist = part->events(); - MusECore::addEventList(evlist, l, track, part, port, channel); + MusECore::addEventList(part->events(), l, track, part, port, channel); } ++i; @@ -529,12 +528,7 @@ void MusE::exportMidi() mf.setDivision(MusEGlobal::config.midiDivision); mf.setTrackList(mtl, i); mf.write(); - - // DELETETHIS 4 ??? or is this still an issue? - // TESTING: Cleanup. I did not valgrind this feature in last memleak fixes, but I suspect it leaked. - //for(MusECore::iMidiFileTrack imft = mtl->begin(); imft != mtl->end(); ++imft) - // delete *imft; - //delete mtl; + } } // namespace MusEGui diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index 449461c5..8b978843 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -142,7 +142,7 @@ map<Event*, Part*> get_events(const set<Part*>& parts, int range) map<Event*, Part*> events; for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) - for (iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++) + for (ciEvent event=(*part)->events().begin(); event!=(*part)->events().end(); event++) if (is_relevant(event->second, *part, range)) events.insert(pair<Event*, Part*>(&event->second, *part)); @@ -784,7 +784,7 @@ bool delete_overlaps(const set<Part*>& parts, int range) Event& event2=*(it2->first); Part* part2=it2->second; - if ( (part1->events()==part2->events()) && // part1 and part2 are the same or are duplicates + if ( (part1->isCloneOf(part2)) && // part1 and part2 are the same or are duplicates (&event1 != &event2) && // and event1 and event2 aren't the same (deleted_events.find(&event2) == deleted_events.end()) ) //and event2 hasn't been deleted before { @@ -844,7 +844,7 @@ bool legato(const set<Part*>& parts, int range, int min_len, bool dont_shorten) if (dont_shorten) relevant = relevant && (event2.tick() >= event1.endTick()); - if ( (part1->events()==part2->events()) && // part1 and part2 are the same or are duplicates + if ( (part1->isCloneOf(part2)) && // part1 and part2 are the same or are duplicates relevant && // they're not too near (respect min_len and dont_shorten) (event2.tick()-event1.tick() < len ) ) // that's the nearest relevant following note len=event2.tick()-event1.tick(); @@ -956,7 +956,7 @@ QMimeData* selected_events_to_mime(const set<Part*>& parts, int range) unsigned start_tick = INT_MAX; //will be the tick of the first event or INT_MAX if no events are there for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) - for (iEvent ev=(*part)->events()->begin(); ev!=(*part)->events()->end(); ev++) + for (ciEvent ev=(*part)->events().begin(); ev!=(*part)->events().end(); ev++) if (is_relevant(ev->second, *part, range)) if (ev->second.tick() < start_tick) start_tick=ev->second.tick(); @@ -981,7 +981,7 @@ QMimeData* selected_events_to_mime(const set<Part*>& parts, int range) for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) { xml.tag(level++, "eventlist part_id=\"%d\"", (*part)->sn()); - for (iEvent ev=(*part)->events()->begin(); ev!=(*part)->events()->end(); ev++) + for (ciEvent ev=(*part)->events().begin(); ev!=(*part)->events().end(); ev++) if (is_relevant(ev->second, *part, range)) ev->second.write(level, xml, -start_tick); xml.etag(--level, "eventlist"); @@ -1158,8 +1158,6 @@ void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part if (create_new_part) { dest_part = dest_track->newPart(); - dest_part->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - // so we must decrement it first :/ dest_part->setTick(AL::sigmap.raster1(first_paste_tick, config.division)); new_part_map[old_dest_part].insert(dest_part); @@ -1231,7 +1229,7 @@ void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part void select_all(const std::set<Part*>& parts) { for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) - for (iEvent ev_it=(*part)->events()->begin(); ev_it!=(*part)->events()->end(); ev_it++) + for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { Event& event=ev_it->second; event.setSelected(true); @@ -1242,7 +1240,7 @@ void select_all(const std::set<Part*>& parts) void select_none(const std::set<Part*>& parts) { for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) - for (iEvent ev_it=(*part)->events()->begin(); ev_it!=(*part)->events()->end(); ev_it++) + for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { Event& event=ev_it->second; event.setSelected(false); @@ -1253,7 +1251,7 @@ void select_none(const std::set<Part*>& parts) void select_invert(const std::set<Part*>& parts) { for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) - for (iEvent ev_it=(*part)->events()->begin(); ev_it!=(*part)->events()->end(); ev_it++) + for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { Event& event=ev_it->second; event.setSelected(!event.selected()); @@ -1265,7 +1263,7 @@ void select_in_loop(const std::set<Part*>& parts) { select_none(parts); for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) - for (iEvent ev_it=(*part)->events()->begin(); ev_it!=(*part)->events()->end(); ev_it++) + for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { Event& event=ev_it->second; event.setSelected((event.tick()>=MusEGlobal::song->lpos() && event.endTick()<=MusEGlobal::song->rpos())); @@ -1277,7 +1275,7 @@ void select_not_in_loop(const std::set<Part*>& parts) { select_none(parts); for (set<Part*>::iterator part=parts.begin(); part!=parts.end(); part++) - for (iEvent ev_it=(*part)->events()->begin(); ev_it!=(*part)->events()->end(); ev_it++) + for (diEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { Event& event=ev_it->second; event.setSelected(!(event.tick()>=MusEGlobal::song->lpos() && event.endTick()<=MusEGlobal::song->rpos())); @@ -1299,10 +1297,9 @@ void shrink_parts(int raster) for (iPart part = (*track)->parts()->begin(); part != (*track)->parts()->end(); part++) if (part->second->selected()) { - EventList* events=part->second->events(); unsigned len=0; - for (iEvent ev=events->begin(); ev!=events->end(); ev++) + for (ciEvent ev=part->second->events().begin(); ev!=part->second->events().end(); ev++) if (ev->second.endTick() > len) len=ev->second.endTick(); @@ -1360,10 +1357,9 @@ void expand_parts(int raster) for (iPart part = (*track)->parts()->begin(); part != (*track)->parts()->end(); part++) if (part->second->selected()) { - EventList* events=part->second->events(); unsigned len=part->second->lenTick(); - for (iEvent ev=events->begin(); ev!=events->end(); ev++) + for (ciEvent ev=part->second->events().begin(); ev!=part->second->events().end(); ev++) if (ev->second.endTick() > len) len=ev->second.endTick(); @@ -1405,8 +1401,7 @@ void clean_parts() // erase all events exceeding the longest clone of this part // (i.e., erase all hidden events) or shorten them - EventList* el = part->second->events(); - for (iEvent ev=el->begin(); ev!=el->end(); ev++) + for (ciEvent ev=part->second->events().begin(); ev!=part->second->events().end(); ev++) if (ev->second.tick() >= len) operations.push_back(UndoOp(UndoOp::DeleteEvent, ev->second, part->second, true, true)); else if (ev->second.endTick() > len) @@ -1465,16 +1460,12 @@ bool merge_parts(const set<Part*>& parts) } // create and prepare the new part - Part* new_part = track->newPart(first_part); + Part* new_part = first_part->duplicateEmpty(); new_part->setTick(begin); new_part->setLenTick(end-begin); - EventList* new_el = new_part->events(); - new_el->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - // so we must decrement it first :/ - new_el->clear(); - // copy all events from the source parts into the new part + EventList& new_el = new_part->events(); for (set<Part*>::iterator p_it=parts.begin(); p_it!=parts.end(); p_it++) if ((*p_it)->track()==track) { @@ -1483,7 +1474,7 @@ bool merge_parts(const set<Part*>& parts) { Event new_event=ev_it->second; new_event.setTick( new_event.tick() + (*p_it)->tick() - new_part->tick() ); - new_el->add(new_event); + new_part->nonconst_events().add(new_event); } } diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index efb4ec68..e71be282 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -941,8 +941,8 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor if (i == sList.end()) { bool used = false; for (MusECore::iPart ip = part_list->begin(); ip != part_list->end(); ++ip) { - MusECore::EventList* el = ip->second->events(); - for (MusECore::iEvent ie = el->begin(); ie != el->end(); ++ie) { + const MusECore::EventList& el = ip->second->events(); + for (MusECore::iEvent ie = el.begin(); ie != el.end(); ++ie) { MusECore::Event e = ie->second; if(e.type() != MusECore::Controller) continue; diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp index e22d865e..7cd69095 100644 --- a/muse2/muse/importmidi.cpp +++ b/muse2/muse/importmidi.cpp @@ -249,8 +249,8 @@ bool MusE::importMidi(const QString name, bool merge) // - calculate tick value for internal resolution // for (MusECore::iMidiFileTrack t = etl->begin(); t != etl->end(); ++t) { - MusECore::MPEventList* el = &((*t)->events); - if (el->empty()) + MusECore::MPEventList& el = ((*t)->events); + if (el.empty()) continue; // // if we split the track, SYSEX and META events go into @@ -264,7 +264,7 @@ bool MusE::importMidi(const QString name, bool merge) MusECore::iMPEvent ev; set< pair<int,int> > already_processed; - for (ev = el->begin(); ev != el->end(); ++ev) + for (ev = el.begin(); ev != el.end(); ++ev) { if (ev->type() != MusECore::ME_SYSEX && ev->type() != MusECore::ME_META) { @@ -288,9 +288,7 @@ bool MusE::importMidi(const QString name, bool merge) track->setOutPort(port); MusECore::MidiPort* mport = &MusEGlobal::midiPorts[port]; - //MusECore::MidiInstrument* instr = mport->instrument(); - MusECore::EventList* mel = track->events(); - buildMidiEventList(mel, el, track, division, first, false); // Don't do loops. + buildMidiEventList(&track->events, el, track, division, first, false); // Don't do loops. first = false; // Comment Added by T356. @@ -305,8 +303,7 @@ bool MusE::importMidi(const QString name, bool merge) { track->setType(MusECore::Track::DRUM); // remap drum pitch with drumOutmap (was: Inmap. flo93 thought this was wrong) - MusECore::EventList* tevents = track->events(); - for (MusECore::iEvent i = tevents->begin(); i != tevents->end(); ++i) { + for (MusECore::iEvent i = track->events.begin(); i != track->events.end(); ++i) { MusECore::Event ev = i->second; if (ev.isNote()) { int pitch = MusEGlobal::drumOutmap[ev.pitch()]; @@ -339,8 +336,7 @@ bool MusE::importMidi(const QString name, bool merge) MusECore::MidiTrack* track = new MusECore::MidiTrack(); track->setOutChannel(0); track->setOutPort(0); - MusECore::EventList* mel = track->events(); - buildMidiEventList(mel, el, track, division, true, false); // Do SysexMeta. Don't do loops. + buildMidiEventList(&track->events, el, track, division, true, false); // Do SysexMeta. Don't do loops. processTrack(track); MusEGlobal::song->insertTrack0(track, -1); } @@ -383,8 +379,8 @@ bool MusE::importMidi(const QString name, bool merge) void MusE::processTrack(MusECore::MidiTrack* track) { - MusECore::EventList* tevents = track->events(); - if (tevents->empty()) + const MusECore::EventList& tevents = track->events; + if (tevents.empty()) return; //--------------------------------------------------- @@ -398,7 +394,7 @@ void MusE::processTrack(MusECore::MidiTrack* track) MusECore::PartList* pl = track->parts(); int lastTick = 0; - for (MusECore::iEvent i = tevents->begin(); i != tevents->end(); ++i) { + for (MusECore::iEvent i = tevents.begin(); i != tevents.end(); ++i) { MusECore::Event event = i->second; int epos = event.tick() + event.lenTick(); if (epos > lastTick) @@ -426,8 +422,8 @@ void MusE::processTrack(MusECore::MidiTrack* track) if (lastOff > x2) { continue; } - MusECore::iEvent i1 = tevents->lower_bound(x1); - MusECore::iEvent i2 = tevents->lower_bound(x2); + MusECore::iEvent i1 = tevents.lower_bound(x1); + MusECore::iEvent i2 = tevents.lower_bound(x2); if (i1 == i2) { // empty? if (st != -1) { @@ -480,28 +476,27 @@ void MusE::processTrack(MusECore::MidiTrack* track) MusECore::MidiPart* part = (MusECore::MidiPart*)(p->second); int stick = part->tick(); int etick = part->tick() + part->lenTick(); - MusECore::iEvent r1 = tevents->lower_bound(stick); - MusECore::iEvent r2 = tevents->lower_bound(etick); + MusECore::iEvent r1 = tevents.lower_bound(stick); + MusECore::iEvent r2 = tevents.lower_bound(etick); int startTick = part->tick(); - MusECore::EventList* el = part->events(); for (MusECore::iEvent i = r1; i != r2; ++i) { MusECore::Event ev = i->second; int ntick = ev.tick() - startTick; ev.setTick(ntick); - el->add(ev); + part->nonconst_events().add(ev); } - tevents->erase(r1, r2); + tevents.erase(r1, r2); } - if (tevents->size()) - printf("-----------events left: %zd\n", tevents->size()); - for (MusECore::iEvent i = tevents->begin(); i != tevents->end(); ++i) { + if (tevents.size()) + printf("-----------events left: %zd\n", tevents.size()); + for (MusECore::ciEvent i = tevents.begin(); i != tevents.end(); ++i) { printf("%d===\n", i->first); i->second.dump(); } // all events should be processed: - if (!tevents->empty()) + if (!tevents.empty()) printf("THIS SHOULD NEVER HAPPEN: not all events processed at the end of MusE::processTrack()!\n"); } @@ -620,7 +615,7 @@ void MusE::importPartToTrack(QString& filename, unsigned tick, MusECore::Track* if (tag == "part") { // Read the part. MusECore::Part* p = 0; - p = readXmlPart(xml, track); + p = Part::readFromXml(xml, track); // If it could not be created... if(!p) { diff --git a/muse2/muse/liste/listedit.cpp b/muse2/muse/liste/listedit.cpp index e1a49842..730ab5d8 100644 --- a/muse2/muse/liste/listedit.cpp +++ b/muse2/muse/liste/listedit.cpp @@ -247,8 +247,8 @@ void ListEdit::songChanged(MusECore::SongChangedFlags_t type) MusECore::MidiPart* part = (MusECore::MidiPart*) (p->second); if (part->sn() == curPartId) curPart = part; - MusECore::EventList* el = part->events(); - for (MusECore::iEvent i = el->begin(); i != el->end(); ++i) { + + for (MusECore::ciEvent i = part->events().begin(); i != part->events().end(); ++i) { EventListItem* item = new EventListItem(liste, i->second, part); for (int col = 0; col < liste->columnCount(); ++col) item->setText(col, item->text(col)); diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index 524329b1..d70b132c 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -198,7 +198,7 @@ QString nameSysex(unsigned int len, const unsigned char* buf) // generally: how to handle incomplete messages //--------------------------------------------------------- -void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, +void buildMidiEventList(EventList* del, const MPEventList& el, MidiTrack* track, int div, bool addSysexMeta, bool doLoops) { int hbank = 0xff; @@ -211,7 +211,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, EventList mel; - for (iMPEvent i = el->begin(); i != el->end(); ++i) { + for (iMPEvent i = el.begin(); i != el.end(); ++i) { MidiPlayEvent ev = *i; if (!addSysexMeta && (ev.type() == ME_SYSEX || ev.type() == ME_META)) continue; @@ -305,7 +305,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, iMPEvent ii = i; ++ii; bool found = false; - for (; ii != el->end(); ++ii) { + for (; ii != el.end(); ++ii) { MidiPlayEvent ev = *ii; if (ev.type() == ME_CONTROLLER) { if (ev.dataA() == CTRL_LDATA) { @@ -471,7 +471,7 @@ void buildMidiEventList(EventList* del, const MPEventList* el, MidiTrack* track, e.setTick(tick); mel.add(e); } - } // i != el->end() + } // i != el.end() //--------------------------------------------------- @@ -625,7 +625,7 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned // dont play muted parts if (part->mute()) continue; - EventList* events = part->events(); + const EventList& events = part->events(); unsigned partTick = part->tick(); unsigned partLen = part->lenTick(); int delay = track->delay; @@ -644,8 +644,8 @@ void Audio::collectEvents(MusECore::MidiTrack* track, unsigned int cts, unsigned if(etick > partLen) continue; - iEvent ie = events->lower_bound(stick); - iEvent iend = events->lower_bound(etick); + ciEvent ie = events.lower_bound(stick); + ciEvent iend = events.lower_bound(etick); for (; ie != iend; ++ie) { Event ev = ie->second; @@ -1009,7 +1009,6 @@ void Audio::processMidi() // if (track->recordFlag()) { - MusECore::MPEventList* rl = track->mpevents(); MusECore::MidiPort* tport = &MusEGlobal::midiPorts[port]; RouteList* irl = track->inRoutes(); for(ciRoute r = irl->begin(); r != irl->end(); ++r) @@ -1063,7 +1062,7 @@ void Audio::processMidi() event.setTime(MusEGlobal::tempomap.frame2tick(event.time())); if(recording) - rl->add(event); + track->mpevents.add(event); } dev->setSysexFIFOProcessed(true); } @@ -1252,7 +1251,7 @@ void Audio::processMidi() drumRecEvent.setB(preVelo); drumRecEvent.setPort(port); //rec-event to current port drumRecEvent.setChannel(track->outChannel()); //rec-event to current channel - rl->add(drumRecEvent); + track->mpevents.add(drumRecEvent); } else { @@ -1263,7 +1262,7 @@ void Audio::processMidi() // different port. That must have been wrong - buildMidiEventList would ignore that. Tim. drumRecEvent.setPort(port); //rec-event to current port drumRecEvent.setChannel(track->outChannel()); //rec-event to current channel - rl->add(drumRecEvent); + track->mpevents.add(drumRecEvent); } } else @@ -1277,7 +1276,7 @@ void Audio::processMidi() recEvent.setPort(port); recEvent.setChannel(track->outChannel()); - rl->add(recEvent); + track->mpevents.add(recEvent); } } } diff --git a/muse2/muse/midi.h b/muse2/muse/midi.h index 86b11c97..c0f6e07f 100644 --- a/muse2/muse/midi.h +++ b/muse2/muse/midi.h @@ -126,7 +126,7 @@ QString midiMetaName(int); class MPEventList; class MidiTrack; -extern void buildMidiEventList(EventList* mel, const MPEventList* el, MidiTrack* track, int division, bool addSysexMeta, bool doLoops); +extern void buildMidiEventList(EventList* mel, const MPEventList& el, MidiTrack* track, int division, bool addSysexMeta, bool doLoops); } // namespace MusECore diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index ebe3a6c8..e1f77bef 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -516,11 +516,10 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace) event.setPitch(npitch); // check for existing event // if found change command semantic from insert to delete - MusECore::EventList* el = part->events(); - MusECore::iEvent lower = el->lower_bound(event.tick()); - MusECore::iEvent upper = el->upper_bound(event.tick()); + MusECore::ciEvent lower = part->events().lower_bound(event.tick()); + MusECore::ciEvent upper = part->events().upper_bound(event.tick()); - for (MusECore::iEvent i = lower; i != upper; ++i) { + for (MusECore::ciEvent i = lower; i != upper; ++i) { MusECore::Event ev = i->second; if(!ev.isNote()) continue; @@ -1027,10 +1026,10 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) if (old_style_drummap_mode) { MusECore::Undo operations; - std::vector< std::pair<MusECore::Part*, MusECore::Event*> > delete_events; + std::vector< std::pair<MusECore::Part*, MusECore::Event> > delete_events; std::vector< std::pair<MusECore::Part*, MusECore::Event> > add_events; - typedef std::vector< std::pair<MusECore::Part*, MusECore::Event*> >::iterator idel_ev; + typedef std::vector< std::pair<MusECore::Part*, MusECore::Event> >::iterator idel_ev; typedef std::vector< std::pair<MusECore::Part*, MusECore::Event> >::iterator iadd_ev; MusECore::MidiTrackList* tracks = MusEGlobal::song->midis(); @@ -1042,9 +1041,9 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) MusECore::MidiPort* mp = &MusEGlobal::midiPorts[curTrack->outPort()]; MusECore::PartList* parts= curTrack->parts(); for (MusECore::iPart part = parts->begin(); part != parts->end(); ++part) { - MusECore::EventList* events = part->second->events(); + const MusECore::EventList& events = part->second->events(); MusECore::Part* thePart = part->second; - for (MusECore::iEvent i = events->begin(); i != events->end(); ++i) { + for (MusECore::ciEvent i = events.begin(); i != events.end(); ++i) { MusECore::Event event = i->second; if(event.type() != MusECore::Controller && event.type() != MusECore::Note) continue; @@ -1058,9 +1057,9 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) } if (pitch == spitch) { - MusECore::Event* spitch_event = &(i->second); - delete_events.push_back(std::pair<MusECore::Part*, MusECore::Event*>(thePart, spitch_event)); - MusECore::Event newEvent = spitch_event->clone(); + const MusECore::Event& spitch_event = i->second; + delete_events.push_back(std::pair<MusECore::Part*, MusECore::Event>(thePart, spitch_event)); + MusECore::Event newEvent = spitch_event.clone(); if(drc) newEvent.setA((newEvent.dataA() & ~0xff) | dpitch); else @@ -1068,9 +1067,9 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) add_events.push_back(std::pair<MusECore::Part*, MusECore::Event>(thePart, newEvent)); } else if (pitch == dpitch) { - MusECore::Event* dpitch_event = &(i->second); - delete_events.push_back(std::pair<MusECore::Part*, MusECore::Event*>(thePart, dpitch_event)); - MusECore::Event newEvent = dpitch_event->clone(); + const MusECore::Event& dpitch_event = i->second; + delete_events.push_back(std::pair<MusECore::Part*, MusECore::Event>(thePart, dpitch_event)); + MusECore::Event newEvent = dpitch_event.clone(); if(drc) newEvent.setA((newEvent.dataA() & ~0xff) | spitch); else @@ -1083,8 +1082,8 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) for (idel_ev i = delete_events.begin(); i != delete_events.end(); i++) { MusECore::Part* thePart = (*i).first; - MusECore::Event* theEvent = (*i).second; - operations.push_back(MusECore::UndoOp(MusECore::UndoOp::DeleteEvent, *theEvent, thePart, true, false)); + const MusECore::Event& theEvent = (*i).second; + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::DeleteEvent, theEvent, thePart, true, false)); } MusECore::DrumMap dm = MusEGlobal::drumMap[spitch]; @@ -1481,18 +1480,17 @@ void DrumCanvas::setStep(int v) //--------------------------------------------------------- // getEventAtCursorPos //--------------------------------------------------------- -MusECore::Event *DrumCanvas::getEventAtCursorPos() +const MusECore::Event* DrumCanvas::getEventAtCursorPos() { if (_tool != CursorTool) return 0; if (instrument_map[cursorPos.y()].tracks.contains(curPart->track())) { - MusECore::EventList* el = curPart->events(); - MusECore::iEvent lower = el->lower_bound(cursorPos.x()-curPart->tick()); - MusECore::iEvent upper = el->upper_bound(cursorPos.x()-curPart->tick()); + MusECore::ciEvent lower = curPart->events().lower_bound(cursorPos.x()-curPart->tick()); + MusECore::ciEvent upper = curPart->events().upper_bound(cursorPos.x()-curPart->tick()); int curPitch = instrument_map[cursorPos.y()].pitch; - for (MusECore::iEvent i = lower; i != upper; ++i) { - MusECore::Event &ev = i->second; + for (MusECore::ciEvent i = lower; i != upper; ++i) { + const MusECore::Event& ev = i->second; if (ev.isNote() && ev.pitch() == curPitch) return &ev; } @@ -1503,7 +1501,7 @@ MusECore::Event *DrumCanvas::getEventAtCursorPos() //--------------------------------------------------------- // selectCursorEvent //--------------------------------------------------------- -void DrumCanvas::selectCursorEvent(MusECore::Event *ev) +void DrumCanvas::selectCursorEvent(const MusECore::Event* ev) { for (iCItem i = items.begin(); i != items.end(); ++i) { diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 1a1ee546..75c9fca3 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -167,8 +167,8 @@ class DrumCanvas : public EventCanvas { virtual void modifySelected(NoteInfo::ValType type, int val, bool delta_mode = true); virtual void keyPress(QKeyEvent* event); virtual void keyRelease(QKeyEvent* event); - MusECore::Event *getEventAtCursorPos(); - void selectCursorEvent(MusECore::Event *ev); + const MusECore::Event* getEventAtCursorPos(); + void selectCursorEvent(const MusECore::Event* ev); int pitch_and_track_to_instrument(int pitch, MusECore::Track* track); diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index 09b33735..ecfc02ba 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -208,8 +208,7 @@ void DList::draw(QPainter& p, const QRect& rect) continue; found = true; - MusECore::EventList* el = cur_part->events(); - for(MusECore::iEvent ie = el->begin(); ie != el->end(); ++ie) + for(MusECore::ciEvent ie = cur_part->events().begin(); ie != cur_part->events().end(); ++ie) { MusECore::Event e = ie->second; if(e.type() != MusECore::Controller) @@ -303,14 +302,14 @@ void DList::draw(QPainter& p, const QRect& rect) continue; found = true; - MusECore::EventList* el = cur_part->events(); + const MusECore::EventList& el = cur_part->events(); //MusECore::PartList* part_list = dcanvas->drumEdit()->parts(); //for(MusECore::ciPart ip = part_list->cbegin(); ip != part_list->cend(); ++ip) { //MusECore::Part* part = ip->second; ///if(part->track() != - //MusECore::EventList* el = part->events(); - for(MusECore::iEvent ie = el->begin(); ie != el->end(); ++ie) + //const MusECore::EventList& el = part->events(); + for(MusECore::ciEvent ie = el.begin(); ie != el.end(); ++ie) { MusECore::Event e = ie->second; if(e.type() != MusECore::Controller) diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index a93ad01e..175287cb 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -1850,8 +1850,8 @@ void DrumEdit::hideUnusedInstruments() for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) if (p->second->track() == track) { - const EventList* el = p->second->cevents(); - for (ciEvent ev=el->begin(); ev!=el->end(); ev++) + const EventList& el = p->second->events(); + for (ciEvent ev=el.begin(); ev!=el.end(); ev++) hide[ev->second.pitch()]=false; } @@ -1883,8 +1883,8 @@ void DrumEdit::hideEmptyInstruments() for (MusECore::ciPart p = parts()->begin(); p != parts()->end(); ++p) if (p->second->track() == track) { - const EventList* el = p->second->cevents(); - for (ciEvent ev=el->begin(); ev!=el->end(); ev++) + const EventList& el = p->second->events(); + for (ciEvent ev=el.begin(); ev!=el.end(); ev++) hide[ev->second.pitch()]=false; } diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index 4ae702f1..d70cc50c 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -192,8 +192,7 @@ void EventCanvas::songChanged(MusECore::SongChangedFlags_t flags) if (etick > end_tick) end_tick = etick; - MusECore::EventList* el = part->events(); - for (MusECore::iEvent i = el->begin(); i != el->end(); ++i) { + for (MusECore::ciEvent i = part->events().begin(); i != part->events().end(); ++i) { MusECore::Event e = i->second; // Do not add events which are past the end of the part. if(e.tick() > len) diff --git a/muse2/muse/midiedit/piano.cpp b/muse2/muse/midiedit/piano.cpp index 40d93910..17553baa 100644 --- a/muse2/muse/midiedit/piano.cpp +++ b/muse2/muse/midiedit/piano.cpp @@ -570,8 +570,7 @@ void Piano::draw(QPainter& p, const QRect& r) int num = cl->num(); int pitch = num & 0x7f; bool used = false; - MusECore::EventList* el = cur_part->events(); - for (MusECore::ciEvent ie = el->begin(); ie != el->end(); ++ie) + for (MusECore::ciEvent ie = cur_part->events().begin(); ie != cur_part->events().end(); ++ie) { MusECore::Event e = ie->second; if(e.type() != MusECore::Controller) diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 92ed3758..1d8039bb 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -635,11 +635,10 @@ void PianoCanvas::pianoCmd(int cmd) if (part == 0) break; - MusECore::EventList* el = part->events(); MusECore::Undo operations; std::list <MusECore::Event> elist; - for (MusECore::iEvent e = el->lower_bound(pos[0] - part->tick()); e != el->end(); ++e) + for (MusECore::ciEvent e = part->events().lower_bound(pos[0] - part->tick()); e != part->events().end(); ++e) elist.push_back((MusECore::Event)e->second); for (std::list<MusECore::Event>::iterator i = elist.begin(); i != elist.end(); ++i) { MusECore::Event event = *i; @@ -663,10 +662,8 @@ void PianoCanvas::pianoCmd(int cmd) break; MusECore::Undo operations; - MusECore::EventList* el = part->events(); - std::list<MusECore::Event> elist; - for (MusECore::iEvent e = el->lower_bound(pos[0]); e != el->end(); ++e) + for (MusECore::ciEvent e = part->events().lower_bound(pos[0]); e != part->events().end(); ++e) elist.push_back((MusECore::Event)e->second); for (std::list<MusECore::Event>::iterator i = elist.begin(); i != elist.end(); ++i) { MusECore::Event event = *i; diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 543e86aa..c1666a78 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -1787,11 +1787,10 @@ void staff_t::create_appropriate_eventlist() for (set<MusECore::Part*>::const_iterator part_it=parts.begin(); part_it!=parts.end(); part_it++) { MusECore::Part* part=*part_it; - MusECore::EventList* el=part->events(); - for (MusECore::iEvent it=el->begin(); it!=el->end(); it++) + for (MusECore::ciEvent it=part->events().begin(); it!=part->events().end(); it++) { - MusECore::Event& event=it->second; + const MusECore::Event& event=it->second; if ( ( event.isNote() && !event.isNoteOff() && // (event.endTick() <= part->lenTick()) ) && @@ -4508,7 +4507,7 @@ void ScoreCanvas::deselect_all() set<MusECore::Part*> all_parts=get_all_parts(); for (set<MusECore::Part*>::iterator part=all_parts.begin(); part!=all_parts.end(); part++) - for (MusECore::iEvent event=(*part)->events()->begin(); event!=(*part)->events()->end(); event++) + for (MusECore::ciEvent event=(*part)->events().begin(); event!=(*part)->events().end(); event++) event->second.setSelected(false); MusEGlobal::song->update(SC_SELECTION); diff --git a/muse2/muse/midievent.h b/muse2/muse/midievent.h index a63fede2..30f0d84f 100644 --- a/muse2/muse/midievent.h +++ b/muse2/muse/midievent.h @@ -36,7 +36,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/muse2/muse/part.cpp b/muse2/muse/part.cpp index 10c7f201..7e99fa2b 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -22,6 +22,7 @@ // //========================================================= +#include <assert.h> #include <stdio.h> #include <cmath> @@ -39,209 +40,52 @@ namespace MusECore { int Part::snGen=0; -//--------------------------------------------------------- -// unchainClone -//--------------------------------------------------------- -void unchainClone(Part* p) +void Part::unchainClone() { - chainCheckErr(p); + chainCheckErr(this); // FIXME proper assert! + + if (_backupClone) printf("THIS SHOULD NEVER HAPPEN: Part::unchainClone() called, but _backupClone was non-NULL\n"); + + _backupClone=_prevClone; // Unchain the part. - p->prevClone()->setNextClone(p->nextClone()); - p->nextClone()->setPrevClone(p->prevClone()); + _prevClone->_nextClone = _nextClone; + _nextClone->_prevClone = _prevClone; // Isolate the part. - p->setPrevClone(p); - p->setNextClone(p); + _prevClone = this; + _nextClone = this; } -//--------------------------------------------------------- -// chainClone -// The quick way - if part to chain to is known... -//--------------------------------------------------------- - -void chainClone(Part* p1, Part* p2) +void Part::chainClone(Part* p) { - chainCheckErr(p1); - - // Make sure the part to be chained is unchained first. - p2->prevClone()->setNextClone(p2->nextClone()); - p2->nextClone()->setPrevClone(p2->prevClone()); + // FIXME assertion - // Link the part to be chained. - p2->setPrevClone(p1); - p2->setNextClone(p1->nextClone()); + this->unchainClone(); - // Re-link the existing part. - p1->nextClone()->setPrevClone(p2); - p1->setNextClone(p2); -} - -//--------------------------------------------------------- -// chainCloneInternal -// No error check, so it can be called by replaceClone() -//--------------------------------------------------------- - -void chainCloneInternal(Part* p) -{ - Track* t = p->track(); - Part* p1 = 0; + // Make our links to the chain + this->_prevClone = p; + this->_nextClone = p->nextClone; - // Look for a part with the same event list, that we can chain to. - // It's faster if track type is known... + // Make the chain's links to us + this->_nextClone->_prevClone = this; + p->_nextClone = this; - 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) - return; - - // 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); -} - -//--------------------------------------------------------- -// chainClone -// The slow way - if part to chain to is not known... -//--------------------------------------------------------- - -void chainClone(Part* p) -{ - chainCheckErr(p); - chainCloneInternal(p); + // Synchronize this->_events to p->_events + this->_events = p->_events; } -//--------------------------------------------------------- -// replaceClone -//--------------------------------------------------------- - -// this replaces p1 by p2. p1 is isolated, and p2 takes its place instead. -void replaceClone(Part* p1, Part* p2) +void Part::rechainClone() { - 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; - } + assert(_backupClone); - // 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); + this->chainClone(_backupClone); + _backupClone = NULL; } +// FIXME FINDMICHJETZT TODO: weg damit! + //--------------------------------------------------------- // unchainTrackParts //--------------------------------------------------------- @@ -441,9 +285,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. @@ -558,8 +401,7 @@ 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(); - 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; @@ -606,7 +448,8 @@ void removePortCtrlEvents(Part* part, bool doClones) iEvent Part::addEvent(Event& p) { - return _events->add(p); + assert(!hasClones()); + return _events.add(p); } //--------------------------------------------------------- @@ -638,66 +481,43 @@ 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; + _backupClone = NULL; setSn(newSn()); _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); - } + +/* FINDMICHJETZT FIXME! +Part* Part::duplicate() const +{ + Part* dup = duplicateEmpty(); -//--------------------------------------------------------- -// MidiPart -// copy constructor -//--------------------------------------------------------- + // 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; +} -MidiPart::MidiPart(const MidiPart& p) : Part(p) +Part* Part::duplicateEmpty() const { - _prevClone = this; - _nextClone = this; -} + MidiPart* part = new MidiPart(this->_track); + part->setName(name()); + part->setColorIndex(colorIndex()); + + *(PosLen*)part = *(PosLen*)this; + part->setMute(mute()); + + return part; +} */ //--------------------------------------------------------- @@ -716,16 +536,6 @@ WavePart::WavePart(WaveTrack* t, EventList* ev) setType(FRAMES); } -//--------------------------------------------------------- -// WavePart -// copy constructor -//--------------------------------------------------------- - -WavePart::WavePart(const WavePart& p) : Part(p) -{ - _prevClone = this; - _nextClone = this; -} //--------------------------------------------------------- @@ -733,19 +543,15 @@ WavePart::WavePart(const WavePart& p) : Part(p) //--------------------------------------------------------- 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(); + } +} //--------------------------------------------------------- @@ -838,14 +644,14 @@ 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); - // TODO FINDMICH FIXME this is totally broken. we don't want to remove events just because they're beyond end-of-part. // we also don't want to auto-resize the last event. /* + 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 @@ -924,7 +730,7 @@ 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) { int l1 = 0; // len of first new part (ticks or samples) int l2 = 0; // len of second new part @@ -933,14 +739,14 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2) switch (type()) { case WAVE: - l1 = samplepos - part->frame(); - l2 = part->lenFrame() - l1; + l1 = samplepos - frame(); + l2 = lenFrame() - l1; break; case MIDI: case DRUM: case NEW_DRUM: - l1 = tickpos - part->tick(); - l2 = part->lenTick() - l1; + l1 = tickpos - tick(); + l2 = lenTick() - l1; break; default: return; @@ -949,11 +755,9 @@ 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: p1->setLenFrame(l1); @@ -973,28 +777,24 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2) p2->setSn(p2->newSn()); - EventList* se = part->events(); - EventList* de1 = p1->events(); - EventList* de2 = p2->events(); - if (type() == WAVE) { - int ps = part->frame(); + 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) { + for (iEvent ie = _events.begin(); ie != _events.end(); ++ie) { 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); } } } @@ -1004,10 +804,10 @@ void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2) 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); } } } @@ -1135,21 +935,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. //--------------------------------------------------------- @@ -1159,7 +944,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) { @@ -1181,7 +966,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) { diff --git a/muse2/muse/part.h b/muse2/muse/part.h index 357ec1db..a9241807 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -60,12 +60,8 @@ typedef CloneList::iterator iClone; class Part : public PosLen { public: enum HiddenEventsType { NoEventsHidden = 0, LeftEventsHidden, RightEventsHidden }; - - // @@@@@@@@@@@ IMPORTANT @@@@@@@@@@@@ - // @@ when adding member variables @@ - // @@ here, don't forget to update @@ - // @@ the copy-constructor! @@ - // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + static Part* readFromXml(Xml&, Track*, bool doClone = false, bool toTrack = true); private: static int snGen; @@ -78,22 +74,23 @@ class Part : public PosLen { protected: Track* _track; - EventList* _events; + EventList _events; Part* _prevClone; Part* _nextClone; + Part* _backupClone; // when a part gets removed, it's still there; and for undo-ing the remove, it must know about where it was clone-chained to. int _hiddenEvents; // Combination of HiddenEventsType. - + public: Part(Track*); - Part(Track*, EventList*); - Part(const Part& p); virtual ~Part(); + virtual Part* duplicate() = 0; + virtual Part* duplicateEmpty() = 0; + virtual Part* createNewClone() = 0; + int sn() { return _sn; } void setSn(int n) { _sn = n; } int newSn() { return snGen++; } - virtual Part* clone() const = 0; - const QString& name() const { return _name; } void setName(const QString& s) { _name = s; } bool selected() const { return _selected; } @@ -102,15 +99,19 @@ class Part : public PosLen { void setMute(bool b) { _mute = b; } Track* track() const { return _track; } void setTrack(Track*t) { _track = t; } - EventList* events() const { return _events; } - const EventList* cevents() const { return _events; } + const EventList& events() const { return _events; } + EventList& nonconst_events() { return _events; } int colorIndex() const { return _colorIndex; } void setColorIndex(int idx) { _colorIndex = idx; } + bool hasClones() { return _prevClone!=this || _nextClone!=this; } + int nClones(); Part* prevClone() { return _prevClone; } Part* nextClone() { return _nextClone; } - void setPrevClone(Part* p) { _prevClone = p; } - void setNextClone(Part* p) { _nextClone = p; } + + void unchainClone(); + void chainClone(Part* p); // *this is made a sibling of p! p is not touched (except for its clone-chain), whereas this->events will get altered + void rechainClone(); // re-chains the part to the same clone chain it was unchained before // Returns combination of HiddenEventsType enum. virtual int hasHiddenEvents() = 0; @@ -118,7 +119,7 @@ class Part : public PosLen { // call this after hasHiddenEvents(). int cachedHasHiddenEvents() const { return _hiddenEvents; } - iEvent addEvent(Event& p); + iEvent addEvent(Event& p); // DEPRECATED. requires the part to be NOT a clone. FIXME remove! virtual void write(int, Xml&, bool isCopy = false, bool forceWavePaths = false) const; @@ -134,10 +135,12 @@ class MidiPart : public Part { public: MidiPart(MidiTrack* t) : Part((Track*)t) {} - MidiPart(MidiTrack* t, EventList* ev) : Part((Track*)t, ev) {} - MidiPart(const MidiPart& p); virtual ~MidiPart() {} - virtual MidiPart* clone() const; + virtual MidiPart* duplicate(); + virtual MidiPart* duplicateEmpty(); + virtual MidiPart* createNewClone(); + + MidiTrack* track() const { return (MidiTrack*)Part::track(); } // Returns combination of HiddenEventsType enum. int hasHiddenEvents(); @@ -154,13 +157,15 @@ class WavePart : public Part { // p3.3.31 AudioConvertMap _converters; - + public: WavePart(WaveTrack* t); WavePart(WaveTrack* t, EventList* ev); - WavePart(const WavePart& p); virtual ~WavePart() {} - virtual WavePart* clone() const; + virtual WavePart* duplicate(); + virtual WavePart* duplicateEmpty(); + virtual WavePart* createNewClone(); + WaveTrack* track() const { return (WaveTrack*)Part::track(); } // Returns combination of HiddenEventsType enum. int hasHiddenEvents(); @@ -191,10 +196,8 @@ class PartList : public std::multimap<int, Part*, std::less<unsigned> > { } }; -extern void chainClone(Part* p); extern void chainClone(Part* p1, Part* p2); extern void unchainClone(Part* p); -extern void replaceClone(Part* p1, Part* p2); extern void chainCheckErr(Part* p); extern void unchainTrackParts(Track* t, bool decRefCount); extern void chainTrackParts(Track* t, bool incRefCount); @@ -202,7 +205,6 @@ extern void addPortCtrlEvents(Part* part, bool doClones); extern void addPortCtrlEvents(Event& event, Part* part, bool doClones); extern void removePortCtrlEvents(Part* part, bool doClones); extern void removePortCtrlEvents(Event& event, Part* part, bool doClones); -extern Part* readXmlPart(Xml&, Track*, bool doClone = false, bool toTrack = true); } // namespace MusECore diff --git a/muse2/muse/remote/pyapi.cpp b/muse2/muse/remote/pyapi.cpp index 7e03fa0e..7d03e36b 100644 --- a/muse2/muse/remote/pyapi.cpp +++ b/muse2/muse/remote/pyapi.cpp @@ -199,9 +199,9 @@ PyObject* getParts(PyObject*, PyObject* args) Py_DECREF(pstrtick2); // Pack midi events into list before wrapping it all up - EventList* events = mpart->events(); + const EventList& events = mpart->events(); PyObject* pyevents = Py_BuildValue("[]"); - for (ciEvent e = events->begin(); e != events->end(); e++) { + for (ciEvent e = events.begin(); e != events.end(); e++) { PyObject* pyevent = PyDict_New(); // The event structure - a dictionary with keys 'type','tick','data' const Event& event = e->second; @@ -331,7 +331,7 @@ bool addPyPartEventsToMusePart(MidiPart* npart, PyObject* part) event.setC(data[2]); event.setTick(etick); event.setLenTick(elen); - npart->events()->add(event); + npart->nonconst_events().add(event); } else printf("Unhandled event type from python: %s\n", type.c_str()); @@ -404,12 +404,12 @@ PyObject* modifyPart(PyObject*, PyObject* part) npart->setLenTick(opart->lenTick()); npart->setSn(opart->sn()); - for (iEvent e = opart->events()->begin(); e != opart->events()->end(); e++) { + for (ciEvent e = opart->events().begin(); e != opart->events().end(); e++) { Event& event = e->second; if (event.type() == Note || event.type() == Controller) continue; - npart->events()->add(event); + npart->nonconst_events()->add(event); } addPyPartEventsToMusePart(npart, part); diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index d457cb1d..a9b9a892 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -577,15 +577,15 @@ bool Song::addEvent(Event& event, Part* part) { // Return false if the event is already found. // (But allow a port controller value, above, in case it is not already stored.) - if(part->events()->find(event) != part->events()->end()) + if(part->events().find(event) != part->events().end()) { // This can be normal for some (redundant) operations. if(MusEGlobal::debugMsg) - printf("Song::addEvent event already found in part:%s size:%zd\n", part->name().toLatin1().constData(), part->events()->size()); + printf("Song::addEvent event already found in part:%s size:%zd\n", part->name().toLatin1().constData(), part->events().size()); return false; } - part->events()->add(event); + part->nonconst_events().add(event); return true; } @@ -595,18 +595,18 @@ bool Song::addEvent(Event& event, Part* part) void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part) { - iEvent i = part->events()->find(oldEvent); + iEvent i = part->nonconst_events().find(oldEvent); - if (i == part->events()->end()) { + if (i == part->nonconst_events().end()) { // This can be normal for some (redundant) operations. if(MusEGlobal::debugMsg) - printf("Song::changeEvent event not found in part:%s size:%zd\n", part->name().toLatin1().constData(), part->events()->size()); + printf("Song::changeEvent event not found in part:%s size:%zd\n", part->name().toLatin1().constData(), part->nonconst_events().size()); // no "return;" because: Allow it to add the new event. (And remove the old one from the midi port controller!) (tim) } else - part->events()->erase(i); + part->nonconst_events().erase(i); - part->events()->add(newEvent); + part->nonconst_events().add(newEvent); } //--------------------------------------------------------- @@ -615,14 +615,14 @@ void Song::changeEvent(Event& oldEvent, Event& newEvent, Part* part) void Song::deleteEvent(Event& event, Part* part) { - iEvent ev = part->events()->find(event); - if (ev == part->events()->end()) { + iEvent ev = part->nonconst_events().find(event); + if (ev == part->nonconst_events().end()) { // This can be normal for some (redundant) operations. if(MusEGlobal::debugMsg) - printf("Song::deleteEvent event not found in part:%s size:%zd\n", part->name().toLatin1().constData(), part->events()->size()); + printf("Song::deleteEvent event not found in part:%s size:%zd\n", part->name().toLatin1().constData(), part->nonconst_events().size()); return; } - part->events()->erase(ev); + part->nonconst_events().erase(ev); } //--------------------------------------------------------- @@ -717,17 +717,10 @@ void Song::changeAllPortDrumCtrlEvents(bool add, bool drumonly) for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) { MidiPart* part = (MidiPart*)(ip->second); - const EventList* el = part->cevents(); - // unsigned len = part->lenTick(); // Commented out by flo, see below - for(ciEvent ie = el->begin(); ie != el->end(); ++ie) + for(ciEvent ie = part->events().begin(); ie != part->events().end(); ++ie) { const Event& ev = ie->second; - // Added by T356. Do not handle events which are past the end of the part. - // Commented out by flo: yes, DO handle them! these are "hidden events" - // which may be revealed later again! - // if(ev.tick() >= len) - // break; - + if(ev.type() != Controller) continue; @@ -780,30 +773,30 @@ void Song::changeACEvent(AudioTrack* t, int acid, int frame, int newFrame, doubl // add recorded Events into part //--------------------------------------------------------- -void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned startTick) +void Song::cmdAddRecordedEvents(MidiTrack* mt, const EventList& events, unsigned startTick) { - if (events->empty()) { + if (events.empty()) { if (MusEGlobal::debugMsg) printf("no events recorded\n"); return; } - iEvent s; - iEvent e; + ciEvent s; + ciEvent e; unsigned endTick; if((MusEGlobal::audio->loopCount() > 0 && startTick > lPos().tick()) || (punchin() && startTick < lPos().tick())) { startTick = lpos(); - s = events->lower_bound(startTick); + s = events.lower_bound(startTick); } else { - s = events->begin(); + s = events.begin(); } // search for last noteOff: endTick = 0; - for (iEvent i = events->begin(); i != events->end(); ++i) { + for (ciEvent i = events.begin(); i != events.end(); ++i) { Event ev = i->second; unsigned l = ev.endTick(); if (l > endTick) @@ -813,10 +806,10 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start if((MusEGlobal::audio->loopCount() > 0) || (punchout() && endTick > rPos().tick()) ) { endTick = rpos(); - e = events->lower_bound(endTick); + e = events.lower_bound(endTick); } else - e = events->end(); + e = events.end(); if (startTick > endTick) { if (MusEGlobal::debugMsg) @@ -856,14 +849,14 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start part->setLenTick(endTick - startTick); part->setName(mt->name()); // copy events - for (iEvent i = s; i != e; ++i) { + for (ciEvent i = s; i != e; ++i) { Event old = i->second; Event event = old.clone(); event.setTick(old.tick() - startTick); // addEvent also adds port controller values. So does msgAddPart, below. Let msgAddPart handle them. //addEvent(event, part); - if(part->events()->find(event) == part->events()->end()) - part->events()->add(event); + if(part->events().find(event) == part->events().end()) + part->nonconst_events().add(event); } MusEGlobal::audio->msgAddPart(part); updateFlags |= SC_PART_INSERTED; @@ -892,8 +885,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start if (_recMode == REC_REPLACE) { - iEvent si = part->events()->lower_bound(startTick - part->tick()); - iEvent ei = part->events()->lower_bound(part->endTick() - part->tick()); + iEvent si = part->nonconst_events().lower_bound(startTick - part->tick()); + iEvent ei = part->nonconst_events().lower_bound(part->endTick() - part->tick()); for (iEvent i = si; i != ei; ++i) { Event event = i->second; @@ -902,7 +895,7 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start // Remove the event from the new part's port controller values, and do all clone parts. removePortCtrlEvents(event, part, true); } - part->events()->erase(si, ei); + part->nonconst_events().erase(si, ei); } for (iEvent i = s; i != e; ++i) { @@ -912,8 +905,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start // Create an undo op. Indicate do port controller values and clone parts. addUndo(UndoOp(UndoOp::AddEvent, e, event, part, true, true)); - if(part->events()->find(event) == part->events()->end()) - part->events()->add(event); + if(part->nonconst_events().find(event) == part->nonconst_events().end()) + part->nonconst_events().add(event); // Add the event to the new part's port controller values, and do all clone parts. addPortCtrlEvents(event, part, true); @@ -921,8 +914,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start } else { if (_recMode == REC_REPLACE) { - iEvent si = part->events()->lower_bound(startTick - part->tick()); - iEvent ei = part->events()->lower_bound(endTick - part->tick()); + iEvent si = part->nonconst_events().lower_bound(startTick - part->tick()); + iEvent ei = part->nonconst_events().lower_bound(endTick - part->tick()); for (iEvent i = si; i != ei; ++i) { Event event = i->second; @@ -931,7 +924,7 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start // Remove the event from the part's port controller values, and do all clone parts. removePortCtrlEvents(event, part, true); } - part->events()->erase(si, ei); + part->nonconst_events().erase(si, ei); } for (iEvent i = s; i != e; ++i) { Event event = i->second; @@ -941,8 +934,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start // Indicate that controller values and clone parts were handled. addUndo(UndoOp(UndoOp::AddEvent, event, part, true, true)); - if(part->events()->find(event) == part->events()->end()) - part->events()->add(event); + if(part->nonconst_events().find(event) == part->nonconst_events().end()) + part->nonconst_events().add(event); // Add the event to the part's port controller values, and do all clone parts. addPortCtrlEvents(event, part, true); @@ -1951,8 +1944,7 @@ void Song::cmdRemovePart(Part* part) { removePart(part); addUndo(UndoOp(UndoOp::DeletePart, part)); - part->events()->incARef(-1); - unchainClone(part); + part->unchainClone(); updateFlags = SC_PART_REMOVED; } @@ -2331,7 +2323,7 @@ void Song::recordEvent(MidiTrack* mt, Event& event) unsigned tick = event.tick(); PartList* pl = mt->parts(); - MidiPart* part = 0; + const MidiPart* part = 0; iPart ip; for (ip = pl->begin(); ip != pl->end(); ++ip) { part = (MidiPart*)(ip->second); @@ -2343,14 +2335,14 @@ void Song::recordEvent(MidiTrack* mt, Event& event) updateFlags |= SC_EVENT_INSERTED; if (ip == pl->end()) { // create new part - part = new MidiPart(mt); + MidiPart* part = new MidiPart(mt); int startTick = roundDownBar(tick); int endTick = roundUpBar(tick + 1); part->setTick(startTick); part->setLenTick(endTick - startTick); part->setName(mt->name()); event.move(-startTick); - part->events()->add(event); + part->nonconst_events().add(event); MusEGlobal::audio->msgAddPart(part); return; } @@ -2361,8 +2353,8 @@ void Song::recordEvent(MidiTrack* mt, Event& event) Event ev; if(event.type() == Controller) { - EventRange range = part->events()->equal_range(tick); - for(iEvent i = range.first; i != range.second; ++i) + EventRange range = part->events().equal_range(tick); + for(ciEvent i = range.first; i != range.second; ++i) { ev = i->second; if(ev.type() == Controller && ev.dataA() == event.dataA()) @@ -2653,7 +2645,7 @@ int Song::execMidiAutomationCtlPopup(MidiTrack* track, MidiPart* part, const QPo unsigned partEnd = partStart + part->lenTick(); if(tick >= partStart && tick < partEnd) { - EventRange range = part->events()->equal_range(tick - partStart); + EventRange range = part->events().equal_range(tick - partStart); for(iEvent i = range.first; i != range.second; ++i) { ev = i->second; @@ -2733,7 +2725,7 @@ int Song::execMidiAutomationCtlPopup(MidiTrack* track, MidiPart* part, const QPo part->setLenTick(endTick - startTick); part->setName(mt->name()); e.setTick(tick - startTick); - part->events()->add(e); + part->nonconst_events().add(e); // Allow undo. MusEGlobal::audio->msgAddPart(part); } @@ -3387,7 +3379,7 @@ void Song::executeScript(const char* scriptfile, PartList* parts, int quant, boo fprintf(fp, "BEATLEN %d\n", AL::sigmap.ticksBeat(0)); fprintf(fp, "QUANTLEN %d\n", quant); - for (iEvent e = part->events()->begin(); e != part->events()->end(); e++) { + for (ciEvent e = part->events().begin(); e != part->events().end(); e++) { Event ev = e->second; if (ev.isNote()) diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 909e54fc..91745c96 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -276,7 +276,7 @@ class Song : public QObject { //----------------------------------------- void cmdAddRecordedWave(WaveTrack* track, Pos, Pos); - void cmdAddRecordedEvents(MidiTrack*, EventList*, unsigned); + void cmdAddRecordedEvents(MidiTrack*, const EventList&, unsigned); bool addEvent(Event&, Part*); void changeEvent(Event&, Event&, Part*); void deleteEvent(Event&, Part*); diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp index 9a583996..9b52791a 100644 --- a/muse2/muse/songfile.cpp +++ b/muse2/muse/songfile.cpp @@ -167,10 +167,10 @@ void Scale::read(Xml& xml) } //--------------------------------------------------------- -// readXmlPart +// Part::readFromXml //--------------------------------------------------------- -Part* readXmlPart(Xml& xml, Track* track, bool doClone, bool toTrack) +Part* Part::readFromXml(Xml& xml, Track* track, bool doClone, bool toTrack) { int id = -1; Part* npart = 0; @@ -347,7 +347,7 @@ Part* readXmlPart(Xml& xml, Track* track, bool doClone, bool toTrack) } else { - npart->events()->add(e); + npart->_events.add(e); } } else // ...Otherwise a clone was created, so we don't need the events. @@ -395,7 +395,6 @@ Part* readXmlPart(Xml& xml, Track* track, bool doClone, bool toTrack) void Part::write(int level, Xml& xml, bool isCopy, bool forceWavePaths) const { - const EventList* el = cevents(); int id = -1; uuid_t uuid; uuid_clear(uuid); @@ -406,7 +405,7 @@ void Part::write(int level, Xml& xml, bool isCopy, bool forceWavePaths) const { for(iClone i = MusEGlobal::cloneList.begin(); i != MusEGlobal::cloneList.end(); ++i) { - if(i->cp->cevents() == el) + if(i->cp->isCloneOf(this)) { uuid_copy(uuid, i->uuid); dumpEvents = false; @@ -422,11 +421,11 @@ void Part::write(int level, Xml& xml, bool isCopy, bool forceWavePaths) const } else { - if (el->arefCount() > 1) + if (this->hasClones()) { for (iClone i = MusEGlobal::cloneList.begin(); i != MusEGlobal::cloneList.end(); ++i) { - if (i->cp->cevents() == el) + if (i->cp->isCloneOf(this)) { id = i->id; dumpEvents = false; @@ -455,7 +454,7 @@ void Part::write(int level, Xml& xml, bool isCopy, bool forceWavePaths) const else xml.nput(level, "<part uuid=\"%s\"", sid); - if(el->arefCount() > 1) + if(hasClones()) xml.nput(" isclone=\"1\""); xml.put(">"); level++; @@ -476,7 +475,7 @@ void Part::write(int level, Xml& xml, bool isCopy, bool forceWavePaths) const if (_mute) xml.intTag(level, "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(level, xml, *this, forceWavePaths); } xml.etag(level, "part"); diff --git a/muse2/muse/steprec.cpp b/muse2/muse/steprec.cpp index 723fe650..466c4e21 100644 --- a/muse2/muse/steprec.cpp +++ b/muse2/muse/steprec.cpp @@ -76,10 +76,10 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct chord_timer->stop(); // extend len of last note? - EventList* events = part->events(); + const EventList& events = part->events(); if (ctrl) { - for (iEvent i = events->begin(); i != events->end(); ++i) + for (iEvent i = events.begin(); i != events.end(); ++i) { Event ev = i->second; if (ev.isNote() && ev.pitch() == pitch && ((ev.tick() + ev.lenTick() + part->tick()) == tick)) @@ -106,8 +106,8 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct // if we would find a note after part->lenTick(), the above "if" // avoids this. this has to be avoided because then part->hasHiddenEvents() is true // which results in forbidding any action beyond its end - EventRange range = events->equal_range(tick - part->tick()); - for (iEvent i = range.first; i != range.second; ++i) + EventRange range = events.equal_range(tick - part->tick()); + for (ciEvent i = range.first; i != range.second; ++i) { Event ev = i->second; if (ev.isNote() && ev.pitch() == pitch) @@ -161,18 +161,18 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct // extend len of last note(s) using std::set; - set<Event*> extend_set; - EventList* events = part->events(); - for (iEvent i = events->begin(); i != events->end(); ++i) + set<const Event*> extend_set; + const EventList& events = part->events(); + for (iEvent i = events.begin(); i != events.end(); ++i) { Event& ev = i->second; if (ev.isNote() && note_held_down[ev.pitch()] && ((ev.tick() + ev.lenTick() + part->tick()) == tick)) extend_set.insert(&ev); } - for (set<Event*>::iterator it=extend_set.begin(); it!=extend_set.end(); it++) + for (set<const Event*>::iterator it=extend_set.begin(); it!=extend_set.end(); it++) { - Event& ev=**it; + const Event& ev=**it; Event e = ev.clone(); e.setLenTick(ev.lenTick() + len); operations.push_back(UndoOp(UndoOp::ModifyEvent,e, ev, part, false, false)); diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp index ad22b8d3..98763a4a 100644 --- a/muse2/muse/structure.cpp +++ b/muse2/muse/structure.cpp @@ -166,8 +166,8 @@ void globalCut(bool onlySelectedTracks) if (part->nextClone()==part) // no clones { // cut Events - EventList* el = part->events(); - for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie) + const EventList& el = part->events(); + for (iEvent ie = el.lower_bound(len); ie != el.end(); ++ie) operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, part, false, false)); } operations.push_back(UndoOp(UndoOp::ModifyPartLength, part, part->lenTick(), len, true, true)); @@ -184,8 +184,6 @@ void globalCut(bool onlySelectedTracks) track->splitPart(part, rpos, p2, p3); delete p2; p3->setTick(lpos); - p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ - p3->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ MusEGlobal::song->informAboutNewParts(part,p1,p3); operations.push_back(UndoOp(UndoOp::DeletePart,part)); @@ -200,7 +198,6 @@ void globalCut(bool onlySelectedTracks) track->splitPart(part, rpos, p1, p2); delete p1; p2->setTick(lpos); - p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ MusEGlobal::song->informAboutNewParts(part,p2); operations.push_back(UndoOp(UndoOp::DeletePart,part)); @@ -259,8 +256,6 @@ Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selec Part* p2; track->splitPart(part, startTicks, p1, p2); p2->setTick(startTicks+moveTicks); - p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ - p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ MusEGlobal::song->informAboutNewParts(part,p1,p2); operations.push_back(UndoOp(UndoOp::DeletePart, part)); @@ -310,19 +305,11 @@ Undo partSplitter(unsigned int pos, bool onlySelectedTracks) Part* p2; track->splitPart(part, pos, p1, p2); - p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - p2->events()->incARef(-1); // so we must decrement it first :/ - MusEGlobal::song->informAboutNewParts(part, p1); MusEGlobal::song->informAboutNewParts(part, p2); operations.push_back(UndoOp(UndoOp::DeletePart,part)); operations.push_back(UndoOp(UndoOp::AddPart,p1)); operations.push_back(UndoOp(UndoOp::AddPart,p2)); - if (MusEGlobal::debugMsg) - { - printf("in partSplitter: part1 %d\n",p1->events()->refCount()); - printf("in partSplitter: part2 %d\n",p2->events()->refCount()); - } break; } } diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index bced64d6..7bb516bb 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -66,9 +66,9 @@ void addPortCtrlEvents(MidiTrack* t) for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) { Part* part = ip->second; - const EventList* el = part->cevents(); + const EventList& el = part->events(); unsigned len = part->lenTick(); - for(ciEvent ie = el->begin(); ie != el->end(); ++ie) + for(ciEvent ie = el.begin(); ie != el.end(); ++ie) { const Event& ev = ie->second; // Added by T356. Do not add events which are past the end of the part. @@ -116,8 +116,8 @@ void removePortCtrlEvents(MidiTrack* t) for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) { Part* part = ip->second; - const EventList* el = part->cevents(); - for(ciEvent ie = el->begin(); ie != el->end(); ++ie) + const EventList& el = part->events(); + for(ciEvent ie = el.begin(); ie != el.end(); ++ie) { const Event& ev = ie->second; @@ -468,8 +468,6 @@ MidiTrack::MidiTrack() : Track(MIDI) { init(); - _events = new EventList; - _mpevents = new MPEventList; clefType=trebleClef; _drummap=new DrumMap[128]; @@ -481,9 +479,6 @@ MidiTrack::MidiTrack() MidiTrack::MidiTrack(const MidiTrack& mt, int flags) : Track(mt, flags) { - _events = new EventList; - _mpevents = new MPEventList; - _drummap=new DrumMap[128]; _drummap_hidden=new bool[128]; @@ -592,27 +587,11 @@ void MidiTrack::internal_assign(const Track& t, int flags) const PartList* pl = t.cparts(); for (ciPart ip = pl->begin(); ip != pl->end(); ++ip) { Part* spart = ip->second; - bool clone = spart->events()->arefCount() > 1; - // This increments aref count if cloned, and chains clones. - // It also gives the new part a new serial number. - Part* dpart = newPart(spart, clone); - if(!clone) { - // Copy Events - MusECore::EventList* se = spart->events(); - MusECore::EventList* de = dpart->events(); - for (MusECore::iEvent i = se->begin(); i != se->end(); ++i) { - MusECore::Event oldEvent = i->second; - MusECore::Event ev = oldEvent.clone(); - de->add(ev); - } - } - - // TODO: Should we include the parts in the undo? - // dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - // // so we must decrement it first :/ - // // These will not increment ref count, and will not chain clones... - // // DELETETHIS: is the above comment still correct (by flo93)? i doubt it! - // operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart)); + Part* dpart; + if (spart->hasClones()) + dpart = spart->createNewClone() + else + dpart = spart->duplicate(); parts()->add(dpart); } @@ -628,8 +607,6 @@ void MidiTrack::assign(const Track& t, int flags) MidiTrack::~MidiTrack() { - delete _events; - delete _mpevents; delete [] _drummap; delete [] _drummap_hidden; @@ -810,7 +787,7 @@ void MidiTrack::setInPortAndChannelMask(unsigned int portmask, int chanmask) Part* MidiTrack::newPart(Part*p, bool clone) { - MidiPart* part = clone ? new MidiPart(this, p->events()) : new MidiPart(this); + MidiPart* part = clone ? p->createNewClone() : new MidiPart(this); if (p) { part->setName(p->name()); part->setColorIndex(p->colorIndex()); @@ -819,10 +796,6 @@ Part* MidiTrack::newPart(Part*p, bool clone) part->setMute(p->mute()); } - if(clone) - //p->chainClone(part); - chainClone(p, part); - return part; } @@ -933,10 +906,7 @@ void MidiTrack::read(Xml& xml) else if (tag == "compression") compression = xml.parseInt(); else if (tag == "part") { - //Part* p = newPart(); - //p->read(xml); - Part* p = 0; - p = readXmlPart(xml, this); + Part* p = Part::readFromXml(xml, this); if(p) parts()->add(p); } @@ -1251,7 +1221,7 @@ int MidiTrack::getFirstControllerValue(int ctrl, int def) { Part* part=pit->second; if (part->tick() > tick) break; // ignore this and the rest. we won't find anything new. - for (iEvent eit=part->events()->begin(); eit!=part->events()->end(); eit++) + for (ciEvent eit=part->events().begin(); eit!=part->events().end(); eit++) { if (eit->first+part->tick() >= tick) break; if (eit->first > part->lenTick()) break; // ignore events past the end of the part @@ -1275,7 +1245,7 @@ int MidiTrack::getControllerChangeAtTick(unsigned tick, int ctrl, int def) Part* part=pit->second; if (part->tick() > tick) break; // ignore this and the rest. we'd find nothing any more if (part->endTick() < tick) continue; // ignore only this. - for (iEvent eit=part->events()->begin(); eit!=part->events()->end(); eit++) + for (ciEvent eit=part->events().begin(); eit!=part->events().end(); eit++) { if (eit->first+part->tick() > tick) break; // we won't find anything in this part from now on. if (eit->first > part->lenTick()) break; // ignore events past the end of the part @@ -1301,7 +1271,7 @@ unsigned MidiTrack::getControllerValueLifetime(unsigned tick, int ctrl) Part* part=pit->second; if (part->tick() > result) break; // ignore this and the rest. we won't find anything new. if (part->endTick() < tick) continue; // ignore only this part, we won't find anything there. - for (iEvent eit=part->events()->begin(); eit!=part->events()->end(); eit++) + for (ciEvent eit=part->events().begin(); eit!=part->events().end(); eit++) { if (eit->first+part->tick() >= result) break; if (eit->first > part->lenTick()) break; // ignore events past the end of the part diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 664364ba..2e8f3af5 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -32,6 +32,7 @@ #include "wave.h" // for SndFileR #include "part.h" +#include "mpevent.h" #include "key.h" #include "node.h" #include "route.h" @@ -41,7 +42,6 @@ #include "controlfifo.h" namespace MusECore { -class MPEventList; class Pipeline; class PluginI; class SynthI; @@ -212,8 +212,11 @@ class MidiTrack : public Track { int _outChannel; bool _recEcho; // For midi (and audio). Whether to echo incoming record events to output device. - EventList* _events; // tmp Events during midi import - MPEventList* _mpevents; // tmp Events druring recording + public: + EventList events; // tmp Events during midi import + MPEventList mpevents; // tmp Events druring recording + + private: static bool _isVisible; clefTypes clefType; @@ -255,9 +258,6 @@ class MidiTrack : public Track { virtual bool setRecordFlag1(bool f) { _recordFlag = f; return true;} virtual void setRecordFlag2(bool) {} - EventList* events() const { return _events; } - MPEventList* mpevents() const { return _mpevents; } - virtual void read(Xml&); virtual void write(int, Xml&) const; diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index 5081f86c..747914e1 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -350,7 +350,7 @@ void Song::doUndo2() removeTrack2(i->track); updateFlags |= SC_TRACK_REMOVED; break; - case UndoOp::DeleteTrack: + case UndoOp::DeleteTrack: // FINDMICHJETZT FIXME TODO: DeletePart on all parts, only empty tracks may be deleted! this removes the necessarity of unchainTrackParts... insertTrack2(i->track, i->trackno); chainTrackParts(i->track, true); @@ -371,15 +371,14 @@ void Song::doUndo2() Part* part = i->part; removePart(part); updateFlags |= SC_PART_REMOVED; - i->part->events()->incARef(-1); - unchainClone(i->part); + Part* i->part->nextClone(); + i->part->unchainClone(); } break; case UndoOp::DeletePart: addPart(i->part); updateFlags |= SC_PART_INSERTED; - i->part->events()->incARef(1); - chainClone(i->part); + i->part->rechainClone(); break; case UndoOp::ModifyPartName: i->part->setName(i->_oldName); @@ -489,14 +488,12 @@ void Song::doRedo2() case UndoOp::AddPart: addPart(i->part); updateFlags |= SC_PART_INSERTED; - i->part->events()->incARef(1); - chainClone(i->part); + i->part->rechainClone(); break; case UndoOp::DeletePart: removePart(i->part); updateFlags |= SC_PART_REMOVED; - i->part->events()->incARef(-1); - unchainClone(i->part); + i->part->unchainClone(); break; case UndoOp::ModifyPartName: i->part->setName(i->_newName); @@ -612,7 +609,7 @@ UndoOp::UndoOp(UndoType type_, Part* part_, unsigned old_len_or_tick, unsigned n new_partlen_or_tick=new_len_or_tick; } -UndoOp::UndoOp(UndoType type_, Event& oev, Event& nev, Part* part_, bool doCtrls_, bool doClones_) +UndoOp::UndoOp(UndoType type_, const Event& oev, const Event& nev, Part* part_, bool doCtrls_, bool doClones_) { assert(type_==ModifyEvent); assert(part_); @@ -625,7 +622,7 @@ UndoOp::UndoOp(UndoType type_, Event& oev, Event& nev, Part* part_, bool doCtrls doClones = doClones_; } -UndoOp::UndoOp(UndoType type_, Event& nev, Part* part_, bool doCtrls_, bool doClones_) +UndoOp::UndoOp(UndoType type_, const Event& nev, Part* part_, bool doCtrls_, bool doClones_) { assert(type_==DeleteEvent || type_==AddEvent); assert(part_); diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index a0b9c935..570fd5ab 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -113,8 +113,8 @@ struct UndoOp { UndoOp(UndoType type, int n, Track* track); UndoOp(UndoType type, Part* part, unsigned old_len_or_tick=-1, unsigned new_len_or_tick=-1, bool doCtrls=false, bool doClones=false); // FIXME these bools are UNUSED!!. XTICKS! UndoOp(UndoType type, Part* part, const char* old_name, const char* new_name); - UndoOp(UndoType type, Event& oev, Event& nev, Part* part, bool doCtrls, bool doClones); - UndoOp(UndoType type, Event& nev, Part* part, bool doCtrls, bool doClones); + UndoOp(UndoType type, const Event& oev, const Event& nev, Part* part, bool doCtrls, bool doClones); + UndoOp(UndoType type, const Event& nev, Part* part, bool doCtrls, bool doClones); UndoOp(UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); UndoOp(UndoType type, Marker* copyMarker, Marker* realMarker); UndoOp(UndoType type, Track* track, const char* old_name, const char* new_name); diff --git a/muse2/muse/wave.cpp b/muse2/muse/wave.cpp index 8c647685..73e4d837 100644 --- a/muse2/muse/wave.cpp +++ b/muse2/muse/wave.cpp @@ -826,11 +826,11 @@ bool SndFile::checkCopyOnWrite() PartList* pl = (*it)->parts(); for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) { - EventList* el = ip->second->events(); + const EventList& el = ip->second->events(); // We are looking for active independent non-clone parts - if(el->arefCount() > 1) + if(ip->second->hasClones()) continue; - for(ciEvent ie = el->begin(); ie != el->end(); ++ie) + for(ciEvent ie = el.begin(); ie != el.end(); ++ie) { if(ie->second.type() != Wave) continue; diff --git a/muse2/muse/waveedit/wavecanvas.cpp b/muse2/muse/waveedit/wavecanvas.cpp index 95ecd250..5bbe2f1f 100644 --- a/muse2/muse/waveedit/wavecanvas.cpp +++ b/muse2/muse/waveedit/wavecanvas.cpp @@ -79,7 +79,7 @@ namespace MusEGui { // WEvent //--------------------------------------------------------- -WEvent::WEvent(MusECore::Event& e, MusECore::Part* p, int height) : MusEGui::CItem(e, p) +WEvent::WEvent(const MusECore::Event& e, MusECore::Part* p, int height) : MusEGui::CItem(e, p) { unsigned frame = e.frame() + p->frame(); setPos(QPoint(frame, 0)); @@ -93,7 +93,7 @@ WEvent::WEvent(MusECore::Event& e, MusECore::Part* p, int height) : MusEGui::CIt // addItem //--------------------------------------------------------- -CItem* WaveCanvas::addItem(MusECore::Part* part, MusECore::Event& event) +CItem* WaveCanvas::addItem(MusECore::Part* part, const MusECore::Event& event) { if (signed(event.frame())<0) { printf("ERROR: trying to add event before current part!\n"); @@ -183,9 +183,8 @@ void WaveCanvas::songChanged(MusECore::SongChangedFlags_t flags) if (esample > endSample) endSample = esample; - MusECore::EventList* el = part->events(); - for (MusECore::iEvent i = el->begin(); i != el->end(); ++i) { - MusECore::Event e = i->second; + for (MusECore::ciEvent i = part->events().begin(); i != part->events().end(); ++i) { + const MusECore::Event& e = i->second; // Do not add events which are past the end of the part. if(e.frame() > len) break; @@ -578,9 +577,9 @@ void WaveCanvas::draw(QPainter& p, const QRect& r) if(ci->isSelected()) list4.push_back(ci); // Draw clone parts, and parts with hidden events, in front of others all except selected. - //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1 || ci->part()->cachedHasHiddenEvents())) + //else if(ci->event().empty() && (ci->part()->hasClones() || ci->part()->cachedHasHiddenEvents())) // Draw clone parts in front of others all except selected. - //else if(ci->event().empty() && (ci->part()->events()->arefCount() > 1)) + //else if(ci->event().empty() && ci->part()->hasClones()) // list3.push_back(ci); else // Draw unselected parts. @@ -1327,9 +1326,9 @@ MusECore::Undo WaveCanvas::moveCanvasItems(MusEGui::CItemList& items, int /*dp*/ MusECore::Part* opart = ip2c->first; if (opart->hasHiddenEvents()) { - forbidden=true; - break; - } + forbidden=true; + break; + } } @@ -1686,11 +1685,11 @@ void WaveCanvas::waveCmd(int cmd) if (part == 0) break; - MusECore::EventList* el = part->events(); + const MusECore::EventList& el = part->events(); MusECore::Undo operations; std::list <MusECore::Event> elist; - for (MusECore::iEvent e = el->lower_bound(pos[0] - part->tick()); e != el->end(); ++e) + for (MusECore::ciEvent e = el.lower_bound(pos[0] - part->tick()); e != el.end(); ++e) elist.push_back((MusECore::Event)e->second); for (std::list<MusECore::Event>::iterator i = elist.begin(); i != elist.end(); ++i) { MusECore::Event event = *i; @@ -1714,10 +1713,10 @@ void WaveCanvas::waveCmd(int cmd) break; MusECore::Undo operations; - MusECore::EventList* el = part->events(); + const MusECore::EventList& el = part->events(); std::list<MusECore::Event> elist; - for (MusECore::iEvent e = el->lower_bound(pos[0]); e != el->end(); ++e) + for (MusECore::ciEvent e = el.lower_bound(pos[0]); e != el.end(); ++e) elist.push_back((MusECore::Event)e->second); for (std::list<MusECore::Event>::iterator i = elist.begin(); i != elist.end(); ++i) { MusECore::Event event = *i; @@ -1927,11 +1926,11 @@ void WaveCanvas::cmd(int cmd) tempPart->setPos(MusEGlobal::song->lpos()); tempPart->setLenTick(MusEGlobal::song->rpos() - MusEGlobal::song->lpos()); // loop through the events and set them accordingly - for (MusECore::iEvent iWaveEvent = origPart->events()->begin(); iWaveEvent != origPart->events()->end(); iWaveEvent++) + for (MusECore::ciEvent iWaveEvent = origPart->events().begin(); iWaveEvent != origPart->events().end(); iWaveEvent++) { // TODO: handle multiple events correctly, // the math for subsequent events isn't correct - MusECore::Event &ev = iWaveEvent->second; + const MusECore::Event& ev = iWaveEvent->second; MusECore::Event *newEvent = new MusECore::Event(ev.clone()); newEvent->setSpos(ev.spos() + frameDistance); newEvent->setLenTick(MusEGlobal::song->rpos() - MusEGlobal::song->lpos()); @@ -1993,10 +1992,9 @@ MusECore::WaveSelectionList WaveCanvas::getSelection(unsigned startpos, unsigned MusECore::WavePart* wp = (MusECore::WavePart*)(ip->second); unsigned part_offset = wp->frame(); - MusECore::EventList* el = wp->events(); - //printf("eventlist length=%d\n",el->size()); + const MusECore::EventList& el = wp->events(); - for (MusECore::iEvent e = el->begin(); e != el->end(); ++e) { + for (MusECore::ciEvent e = el.begin(); e != el.end(); ++e) { MusECore::Event event = e->second; if (event.empty()) continue; diff --git a/muse2/muse/waveedit/wavecanvas.h b/muse2/muse/waveedit/wavecanvas.h index 10f75291..63979915 100644 --- a/muse2/muse/waveedit/wavecanvas.h +++ b/muse2/muse/waveedit/wavecanvas.h @@ -64,7 +64,7 @@ namespace MusEGui { class WEvent : public CItem { public: - WEvent(MusECore::Event& e, MusECore::Part* p, int height); + WEvent(const MusECore::Event& e, MusECore::Part* p, int height); }; //--------------------------------------------------------- @@ -124,7 +124,7 @@ class WaveCanvas : public EventCanvas { virtual void dragEnterEvent(QDragEnterEvent* event); virtual void dragMoveEvent(QDragMoveEvent*); virtual void dragLeaveEvent(QDragLeaveEvent*); - virtual CItem* addItem(MusECore::Part*, MusECore::Event&); + virtual CItem* addItem(MusECore::Part*, const MusECore::Event&); int y2pitch(int) const; int pitch2y(int) const; diff --git a/muse2/muse/waveedit/waveview.cpp b/muse2/muse/waveedit/waveview.cpp index 3e3ea057..2cb63dc5 100644 --- a/muse2/muse/waveedit/waveview.cpp +++ b/muse2/muse/waveedit/waveview.cpp @@ -119,9 +119,8 @@ void WaveView::pdraw(QPainter& p, const QRect& rr) int channels = wp->track()->channels(); int px = wp->frame(); - MusECore::EventList* el = wp->events(); - for (MusECore::iEvent e = el->begin(); e != el->end(); ++e) { - MusECore::Event event = e->second; + for (MusECore::ciEvent e = wp->events().begin(); e != wp->events().end(); ++e) { + const MusECore::Event event& = e->second; if (event.empty()) continue; MusECore::SndFileR f = event.sndFile(); diff --git a/muse2/muse/waveevent.h b/muse2/muse/waveevent.h index e814fe3d..e539342c 100644 --- a/muse2/muse/waveevent.h +++ b/muse2/muse/waveevent.h @@ -44,7 +44,7 @@ class WaveEventBase : public EventBase { int _spos; // start sample position in WaveFile bool deleted; - virtual EventBase* clone(); + virtual EventBase* clone() const; public: WaveEventBase(EventType t); diff --git a/muse2/muse/wavetrack.cpp b/muse2/muse/wavetrack.cpp index 363f8966..4faaca43 100644 --- a/muse2/muse/wavetrack.cpp +++ b/muse2/muse/wavetrack.cpp @@ -60,27 +60,11 @@ void WaveTrack::internal_assign(const Track& t, int flags) const PartList* pl = t.cparts(); for (ciPart ip = pl->begin(); ip != pl->end(); ++ip) { Part* spart = ip->second; - bool clone = spart->events()->arefCount() > 1; - // This increments aref count if cloned, and chains clones. - // It also gives the new part a new serial number. - Part* dpart = newPart(spart, clone); - if(!clone) { - // Copy Events - MusECore::EventList* se = spart->events(); - MusECore::EventList* de = dpart->events(); - for (MusECore::iEvent i = se->begin(); i != se->end(); ++i) { - MusECore::Event oldEvent = i->second; - MusECore::Event ev = oldEvent.clone(); - de->add(ev); - } - } - - // TODO: Should we include the parts in the undo? - // dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - // // so we must decrement it first :/ - // // These will not increment ref count, and will not chain clones... - // // DELETETHIS: is the above comment still correct (by flo93)? i doubt it! - // operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart)); + Part* dpart; + if (spart->hasClones()) + dpart = spart->createNewClone() + else + dpart = spart->duplicate(); parts()->add(dpart); } @@ -127,8 +111,7 @@ void WaveTrack::fetchData(unsigned pos, unsigned samples, float** bp, bool doSee if (pos >= p_epos) continue; - EventList* events = part->events(); - for (iEvent ie = events->begin(); ie != events->end(); ++ie) { + for (iEvent ie = part->nonconst_events().begin(); ie != part->nonconst_events().end(); ++ie) { Event& event = ie->second; unsigned e_spos = event.frame() + p_spos; unsigned nn = event.lenFrame(); @@ -205,7 +188,7 @@ void WaveTrack::read(Xml& xml) case Xml::TagStart: if (tag == "part") { Part* p = 0; - p = readXmlPart(xml, this); + p = Part::readFromXml(xml, this); if(p) parts()->add(p); } @@ -231,7 +214,7 @@ void WaveTrack::read(Xml& xml) Part* WaveTrack::newPart(Part*p, bool clone) { - WavePart* part = clone ? new WavePart(this, p->events()) : new WavePart(this); + WavePart* part = clone ? p->createNewClone() : new WavePart(this); if (p) { part->setName(p->name()); part->setColorIndex(p->colorIndex()); @@ -240,9 +223,6 @@ Part* WaveTrack::newPart(Part*p, bool clone) part->setMute(p->mute()); } - if(clone) - chainClone(p, part); - return part; } diff --git a/muse2/muse/widgets/utils.cpp b/muse2/muse/widgets/utils.cpp index ab1d74fd..0cb10a20 100644 --- a/muse2/muse/widgets/utils.cpp +++ b/muse2/muse/widgets/utils.cpp @@ -532,7 +532,7 @@ int get_paste_len() if (tag == "part") { Part* p = 0; - p = readXmlPart(xml, NULL, false, false); + p = Part::readFromXml(xml, NULL, false, false); if (p) { @@ -542,7 +542,7 @@ int get_paste_len() if (p->endTick() > end_tick) end_tick=p->endTick(); - unchainClone(p); + p->unchainClone(); delete p; } } |